背景知识:
线程 (thread) 线程指代可执行代码的一部分
进程 (process) 指代可执行代码,可以包含多个线程
线程间同步的目的
解决多个线程读写同一个数据时,造成的数据错乱问题
线程间同步的方式
- 互斥锁 (Mutex)
- 目的:保证同一时刻只有一段代码进入临界区进行操作。
- 做法:
- 第一段代码进入临界区之后,执行加锁操作。
- 进入临界区之前检查锁变量的bool值,如果为false则会放弃cpu等待进入挂起状态,保存上下文切换部分。
- 直到锁的状态发生改变时再唤醒,线程激活进行恢复上下文。
- 问题:由于存储、恢复上下文会带来一定的开销,不要在性能敏感的地方使用
- 自旋锁 (spinlock)
- 目的:为了节约互斥锁存储恢复上下文的造成的开销。
- 做法:线程反复检查锁变量是否可用。
while (抢锁(lock)==没抢到) {
}
- 问题: 会造成忙等待。
- 信号量 (Semaphore)
- 目的:不需要使用忙等待的方法。在信号量只有0或1的时候就是互斥锁。
- 做法:
- 创建一个同步对象作为信号量,该计数值范围为0到最大值。
- 线程对信号量等待 (wait) 时,计数值减一;线程对信号量释放 (release) 时,计数值加一。
会出现的问题
- 死锁 (deadlock)
- 出现时机: 两个以上的线程,双方都在等待对方停止运行,以继续运行,但没有一方提前退出。
- 数据竞争 (race hazard)
- 出现时机:两个进程同时修改一个共享内容,没有并发控制的情况下,最后结果依赖于进程的执行顺序。并有可能会发生并发访问冲突。
网友评论