并发编程基本模型
message passing和shared memory。

线程同步的四项原则

  • 尽量最低限度地共享对象,减少需要同步的场合。如果确实需要,优先考虑共享 immutable 对象。
  • 使用高级的并发编程构件,如TaskQueue、Producer-Consumer Queue、CountDownLatch等等。
  • 不得已必须使用底层同步原语(primitives)时,只用非递归的互斥器和条件变量,慎用读写锁,不要用信号量。
  • 除了使用 atomic 整数之外,不自己编写 lock-free 代码,也不要用“内核级”同步原语。不凭空猜测“哪种做法性能会更好”,比如 spin lock vs. mutex。

互斥器的使用

  • 用 RAII 手法封装 mutex 的创建、销毁、加锁、解锁这四个操作。保证锁的生效期间等于一个作用域(scope)。
  • 只用非递归的 mutex(即不可重入的 mutex)。
  • 不手工调用 lock() 和 unlock() 函数,一切交给栈上的 Guard 对象的构造和析构函数负责(Scoped Locking)。
  • 在每次构造 Guard 对象的时候,思考一路上(调用栈上)已经持有的锁,防止因加锁顺序不同而导致死锁。

条件变量的使用

  • 对于 wait() 端:
    必须与 mutex 一起使用,该布尔表达式的读写需受此 mutex 的保护。
    在 mutex 已上锁的情况下才能调用 wait()。
    把判断布尔表达式和 wait() 放在 while 循环中。

  • 对于 signal/broadcast 端:
    不一定要在 mutex 已上锁的情况下调用 signal(理论上)。
    在 signal 之前一般要修改布尔表达式。
    修改布尔表达式通常需要用 mutex 保护(至少用作 full memory barrier)。
    broadcast 通常用于表明状态变化,signal 通常用于表示资源可用。

  • 虚假唤醒(spurious wakeup),Linux 中 futex 慢速系统调用被信号打断返回 -1,wait 返回了。

读写锁与信号量的使用

  • 从正确性方面来说,一种典型的易犯的错误是在持有 reader lock 的时候修改了共享数据。
  • 从性能方面来说,读写锁不见得比普通 mutex 更高效。
  • reader lock 可能允许提升为 writer lock,也可能不允许提升。
  • 通常 reader lock 是可重入的,writer lock 是不可重入的。
  • 信号量不是必备的同步原语,因为条件变量配合互斥器可以完全替代其功能,而且更不易用错。

参考:《Linux多线程服务端编程》。

《Linux多线程服务端编程》笔记——线程同步精要的更多相关文章

  1. 一、智能指针及线程同步总结------linux多线程服务端编程

    更新2.0 二.多线程及服务器编程总结------linux多线程服务端编程 https://www.cnblogs.com/l2017/p/11335609.html 三.分布式编程总结------ ...

  2. 《Linux多线程服务端编程》笔记——多线程服务器的适用场合

    如果要在一台多核机器上提供一种服务或执行一个任务,可用的模式有 运行一个单线程的进程 运行一个多线程的进程 运行多个单线程的进程 运行多个多线程的进程 这些模式之间的比较已经是老生常谈,简单地总结 模 ...

  3. Linux多线程服务端编程一些总结

    能接触这本书是因为上一个项目是用c++开发基于Linux的消息服务器,公司没有使用第三方的网络库,卷起袖子就开撸了.个人因为从业经验较短,主 要负责的是业务方面的编码.本着兴趣自己找了这本书.拿到书就 ...

  4. 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册

    <Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...

  5. 《Linux 多线程服务端编程:使用 muduo C++ 网络库》电子版上市

    <Linux 多线程服务端编程:使用 muduo C++ 网络库> 电子版已在京东和亚马逊上市销售. 京东购买地址:http://e.jd.com/30149978.html 亚马逊Kin ...

  6. 《Linux多线程服务端编程——使用muduo C++网络库》读书笔记

    第一章 线程安全的对象生命期管理 第二章 线程同步精要 第三章 多线程服务器的适用场合与常用编程模型 第四章 C++多线程系统编程精要 1.(P84)11个常用的最基本Pthreads函数: 2个:线 ...

  7. Linux多线程服务端编程:使用muduo C++网络库

    内容推荐本 书主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread.这 ...

  8. Linux多线程服务端编程 使用muduo C++网络库 学习笔记 日志log

    代码来自陈硕开源代码库 muduo中 地址是https://github.com/chenshuo/muduo #pragma once #include <string> #define ...

  9. <Linux多线程服务端编程>学习记录

    使用智能指针解决多线程下 类的解析冲突问题 有这样一个场景 使用StockFactory记录Stock的信息  容器是map<string,smart_ptr>; 代码如下: #inclu ...

随机推荐

  1. Unity3d之剥离alpha通道

    unity中, 将图集的 alpha 通道剥离出来可减少包体大小和内存使用大小. 方法是将原来的一张 rgba 图分成一张 rgb 和一张 alpha 图,android上rgb和alpha图均采用e ...

  2. VS2012配置Cocos2d-x的问题

    cocos2d-x老是配置不成功,解决方案参考:http://blog.csdn.net/yangjingui/article/details/9408007 完整配置流程: 1 下载,最好通过SVN ...

  3. Go Runtime hashmap实现

    努力学习go中,看到skoo博客内容很不错, 所以转载学习下 前两天有小伙伴问道是否看过 Go 语言 map 的实现,当时还真没看过,于是就花了一点时间看了一遍 runtime 源码中的 hashma ...

  4. 用C语言写一个“事件”的模拟程序

    源:用C语言写一个“事件”的模拟程序 Example.c //定义一个函数指针 func int (*func) (void); //调用该函数相当于触发了事件. //该事件触发后,会检查函数指针fu ...

  5. 贪心法基础题目 HDU

    贪心算法的基本步骤: 1.从问题的某个初始解出发.2.采用循环语句,当可以向求解目标前进一步时,就根据局部最优策略,得到一个部分解,缩小问题的范围或规模.3.将所有部分解综合起来,得到问题的最终解. ...

  6. JDBC操作数据时中文乱码

    /** * DB地址 */ private static final String DB_URL="jdbc:mysql://localhost:3306/db_book?useUnicod ...

  7. iOS强制切换横屏、竖屏

    切换横竖屏最直接的方式是调用device的setOrientation方法.但是从sdk3.0以后,这个方法转为似有API,如果要上AppStore的话,要慎用! if ([[UIDevice cur ...

  8. svn 几个好用的命令

    Mac下操作的命令 1. 删除目录及子目录下,未添加的文件 svn status . | grep '^?' | awk '{print $2}' | xargs rm -rf 2.恢复根目录及子目录 ...

  9. Android与JNI(三) ---- c++调用java(转载)

    源码下载:JniDemo JNI就是Java Native Interface, 即可以实现Java调用本地库, 也可以实现C/C++调用Java代码, 从而实现了两种语言的互通, 可以让我们更加灵活 ...

  10. mongodb学习(二)分级查询数组中的值

    (PS: 标题有点不妥当...) 大概是这样...数据结构如下: 需要模糊查询title的值... mongodb中操作语句: 主要是注意这里urlElements不需要加[0]...我开始的时候写成 ...