第2章 线程同步精要
P31 并发编程的两种模型: 1.message passing 2.shared memory
1.多进程:
分布式系统message passing 实际是唯一,单机也可照搬。
2.多线程编程, message passing 更容易保证正确性
C/C++多线程编程 , 仍然需要了解底层的 shared memory
———————— 意思是不是实际上 C/C++多线程也基本上是用message passing,本章是补 shared memory的缺 ???
线程同步4原则:
1. 尽量少共享,少同步
2. 使用 task queue, producer-consumer queue, countdownlatch
3. 不得已的选择: 非递归互斥器, 条件变量, 读写锁, 信号量
—————— 本章即是 分析这几个东西
4. ………………
2.1 mutex
4大原则
5小原则
2.1.1 只使用 非递归mutex
1. 不为性能,为体现设计意图
2. 递归mutex方便,但可能会隐藏问题。
使用非递归mutex容易定位问题
例子中的问题:遍历时修改vector, 两种做法
1. 推迟
2. copy-on-write S2.8补充
函数存在已加锁,未加锁两种情况,拆成两个函数
可能导致两个问题:
a. 误用加锁, 仿造2.1.2来排错
b. 误用不加锁,使用isLockedByThisThread()解决
annotation ??? ————不懂
2.1.2 进一步说明死锁的问题
1. 线程自己与自己死锁
2. 两个线程死锁
P40 补充一个引子, 锁使用不当影响性能。
2.2 condition variable
与 mutex的区别: mutex是排他性访问, 条件变量是等带条件成立
使用方法:
1. wait端: 3点
spurious wakeup ??? ————不懂
2. signal/broadcast端: 4点
(上面的例子其实已经实现了BlockingQueue)
但是“condition variable”太底层了,来用封装成BlockingQueue / CountdownLatch
CountdownLatch的两种用途:
阶段性总结: 互斥器和条件变量是全部必备同步原语
2.3 不要用剩下的两个: 读写锁 ,信号量
1, 批判读写锁:
a. 一见到,就
b. 甚至首选
4个理由:
a. 正确性
b. 性能
c. 提升 死锁
d. 重入 死锁
总结:mudou 不用读写锁,首选 mutex
替代方案: 1. 避免阻塞,用S2.8 的方法
2. 极高性能要求场合:read-copy-update ————不懂,
2. 批判信号量:
原因: a. 不必须, b.有自己计数值
控制并发度,用mudou::ThreadPool
复杂IPC问题,检讨设计,宁愿用集权模式
补充Pthreads的barrier,不如CountdownLatch
2.4 终于上代码了,
1.MutexLock的实现
2.MutexLockGuard的实现
3.Condition Class的实现
批判下boost
补充说明: 不要用铅笔刀锯大树
2.5 线程安全的Singleton实现
DCL ??? ————不懂
使用pthread_once
2.6 三个sleep 不能用来做同步
2.7 总结
尽量用高层同步设施
性能问题是锁争用
2.8 补充2.1提到的几个问题 ,用shared_ptr实现copy-on-write
补充用mutex代替读写锁
.
--
修改:CyberPunker FROM 203.218.252.*
FROM 203.218.252.*