前言
最近在读陈硕的moduo网络库的书,记录总结一些东西。在并发编程中,有两种基本模型,一种是message passing,另外一种是Shared memory。这一章主要讲述shared memory模型下线程同步需要注意的一些问题。作者陈硕推荐尽可能使用message passing,因为其更容易保证程序的正确性,并且可以移植到分布式系统中,扩容性更强。但是多线程编程仍然需要程序员了解shared memory情形,以备不时之需。
本章题名为“线程同步精要”,又在文章开头提到并发编程的两种基本模型,私以为,线程同步精要指的单单是shared memory,只有线程间共享的资源,才需要采取同步措施来保证资源的正确访问。本章作者分享的是他个人在线程同步方面的经验与心得。
线程同步的四项原则
文中按照重要性先后列出线程同步的四项原则
- 首要原则是尽量最低限度地共享对象,减少需要同步的场合。一个对象能不暴露给别的线程就不要暴露;如果要暴露,优先考虑immutable对象;实在不行才暴露可修改的对象,并用同步措施来充分的保护它。
- 其次是使用高级的并发编程构件,如TaskQueue、Producer-Consumer Queue、CountDownLatch等等。
- 最后不得已必须使用底层同步原语(primitives)时,只用非递归的互斥器和条件变量,慎用读写锁,不要用信号量。
- 除了使用atomic整数之外,不自己编写lock-free代码,也不要用“内核级”同步原语。不凭空猜测“哪种做法性能更好”,比如“spin lock vs.
原则第三条
互斥器
互斥器,很简单,就是RAII收发,常见的MutexLock和MutexLockGuard手法,MutexLock负责锁的创建和销毁以及判断是否被锁,MutexLockGuard负责加锁解锁(即临界区的进入和退出)。
作者推荐使用非递归锁,因为同一个线程中多次对非递
打开core dump
ulimit -a # 检查生成 core 文件的选项是否打开
若未打开,修改/etc/profile
,在最后一行加入
# /dev/null 表示linux上的一个文件设备,所有不想存储数据的程序,都可以将输出定向到该文件上
# 2是标准错误,&1就是第一个文件句柄(即/dev/null),这里表示标准输出也不显示
ulimit -S -c unlimited > /dev/null 2>&1
想要立即生效,则
source /etc/profile
否则,需要重启才能生效
修改core的文件格式
修改 /etc/sysctl.conf,添加下面两行
# %e表示文件名,%p表示进程号, %t表示core dump时的时间
kernel.core_pattern = %e.core.%p.%t
kernel.core_uses_pid = 1
想要及时生效,需要sudo /sbin/sysctl -e -p /etc.sysctl.conf
或者直接 sudo sysctl -p
为了保证每次重启之后仍然生效,需要修改启动项里面的东西,在ubuntu14.04中,可以修改/etc/rc.local
文件,加入
/sbin/sysctl -p
其他
另外让kernel参数即时生效的一些办法
ruiy@ruiy-All-Series:~$ sudo sysctl -w kernel.core_uses_pid=0
[sudo] ruiy 的密码:
kernel.core_uses_pid = 0
ruiy@ruiy-All-Series:~$ cat /proc/sys/kernel/core_uses_pid
0
ruiy@ruiy-All-Series:~$
前言
在c++多线程编程中,线程间可能会使用跨线程对象,那么对象在什么时候销毁便成了一个让人头疼的问题,因为一个线程在使用这个对象时,另外一个线程可能正在析构这个对象。该章内容就是为我们解读,如何正确的处理跨线程对象的生命周期,以避免内存泄露、空悬指针或者使得程序处于不确定状态等问题。
线程安全
什么是线程安全?这里给出书中的定义:
一个线程安全的class应当满足以下三个条件:
- 多个线程同时访问时,能够表现出正确的行为
- 无论操作系统如何调度这些线程,无论这些线程的执行顺序如何交织
- 调用段代码无须额外的同步或者其他协调动作
依据这个定义,c++标准库中大多数class都不是线程安全的,包括std::string、std::vector、std::map等,因为这些class通常需要在外部加锁才能供多个线程同时访问
个人的理解就是,一个线程安全的类,即使不用在外部加锁,也可以在多个线程中同时访问,想想,实现这样的类,就很难,这也是为什么多线程编程是我一直想去积累一些东西的原因,这是座山,而我必须得翻过。
多线程中的析构与智能指针
由于在多线程环境中,一个对象可以同时被多个线程访问,这导致析构该对象的时机变得模糊不清。很有可能该对象在一个线程中被访问,而同时在另外一个线程中被析构,这些都会造成程序处于未知的状态。那么我们是否可以加锁来保证析构时,其他线程不会访问呢?遗憾的是,析构时锁作为对象的一部分也会被析构,这样就无法对临界区进行保护。
实际上,我们在多线程编程使用原始指针时,不得不思考一个问题,那就是什么时候对象的析构才是安全的?只有其他线程都访问不到该对象的时候才是安全的。自然而然,我们可以想到使用智能指针来引入一层间接性的引用计数。对于跨线程对象而言,最好使用标准库中的智能指针进行处理,智能指针的核心是引用计数。智能指针的思想符合用对象管理资源的思路,实际上,现代c++程序一般不会出现内存泄露的情况,除非特别情况,一般都会使用容器或者智能指针来管理资源。
用智能指针代替原始指针的一大好处是原始指针无法判断所指内存上的对象是否销毁,而只要有智能指针引用计数不为0,所指涉内存上的对象便不会被销毁。
观察者模式与智能指针
#include <algorithm> #include <vector> #include <stdio.h> cl
来到渣浪已经一百天,西二旗一直是相同的容颜
早高峰的西二旗就像儿时赶集的菜市场,人满为患。思绪回到7月8号那天在无线谷买火车票的那天,实验室项目走不开和南京这边大公司的实习机会太少的焦虑无法遏止,非常烦躁,思来想去,决定直接先去北京,如果有机会,就直接去面试。
7月10号那天下午,我怀着十分忐忑的心情坐上北上的高铁,彼时工作未定,居无定所。后来这些在一周之内都搞定了,想来,人品还不算太坏。大三的校招虽然不是很顺利,一次次挫败却让我面对面试官时愈发得心应手。
7月17日,周三,小雨,入职,一切似乎驾轻就熟,没有太多兴奋,因为已经习惯,毕竟早就从一个新兵蛋子成长为一个老油条。因为新浪是统一办理实习生入职的,所以在一个会议室里坐满了来入职的实习生。看着这些娃娃,似乎看到了几年前的自己。
工作
期间三个月,主要负责的工作就是维护系统和编写新的需求,和业务关联不大。我这边主要是负责的事情和三个系统有关联,一个是部门内部用的平台“微博安全中心”,这个平台主要是开发给部门内人员使用的,比如说反抓站,反盗号等等。第二个是公司内部使用的平台,风险控制平台,可以查询一些uid的登录信息,封禁情况啊等等。第三个是开放给外部的“应急响应中心”的后台,比如漏洞的提交、审核,奖品的发放等等。基本上,新需求没有什么难度,在老系统上扩展功能而已,web开发方面的东西,我再熟悉不过了,无非就是换语言、换框架的事情,当然了这边实习生的事情也不是非常重,所以工作上毫无压力,完全hold得住。
比较遗憾的是,部门的web技术有一部分比较落后,这三个系统都是构建在CodeIgniter上,CodeIgniter虽然相比Laravel要轻量一些,但是相比Laravel来说还是不行。在PHP框架里面,Laravel是我比较喜欢的框架,成熟的架构设计(中间件、数据迁移、服务容器和Composer的结合、还有超好用的blade模板引擎),CI这么一看除了快糙猛之外,我感觉没有什么优势,而且社区也没有Laravel活跃。(Laravel真的很优雅,对开发者很说很舒服,不怕没有货,就怕货比货)。
另外这边比较坑的一点是实习生没有权限上服务器,没有权限上服务器也就罢了,部门里面web方面还没有搭建起一个合理成熟的本地开发环境,或者说流程。每次我必须使用rsync同步到测试服务器上,然后在测试环境上看,如果开发前端的话,简直就是遭罪,非
前因
我是拒绝在windows下写程序的,然而...黄老怪非要vs2012的环境下写课程作业...无奈下...我还得用vs下使用Qt...
环境
VS 2015 和 Qt5.11.0
VS安装插件和配置qt
工具 -> 扩展和更新 -> 联机 -> 搜索Qt即有插件Qt Visual Studio Tools
Qt VS Tools -> Qt Options 配置对应版本的安装路径,比如 D:\Qt\5.11.0\msvc2015_64
Qt5.11.0
官网上下载opensource版本,然后安装时选择msvs的编译器就好
安装debug tool for windows
参考:https://blog.csdn.net/liang19890820/article/details/53931813
去这里下载安装调试工具,安装时选择debug tool for windows
此工具用于vs调试用
vs生成pro文件
Qt5 -> creat basic .pro file 创建Qt工程所要的项目文件,这样就可以用QtCreator开发,因为有些功能Vs开的Qt designer并没有,比如转到槽...
开发过程
建议还是Qt Creator下新建项目之后,再通过VS QT插件-> open Qt .pro file(可能报Project ERROR: Cannot run compiler 'cl'. Maybe you forgot to setup the environment?这种错误,把VS安装目录的bin路径加入环境变量就行了)直接导入比较好。以避免各种各样修改qmake配置文件的问题。。。
Qt和Crypto++库如何并存
Crypto++源代码下载下来之后,点开.sln文件,使用vs编译时需要制定工程->vc/c++->代码生成->运行库 为 MDd,即多线程调试DLL,然后再把Output->debug下的lib文件复制到响应的lib目录下...不然到时候会报这种错误http://stackoverflow.org.cn/front/ask/view?ask_i