一、为什么需要进程间的同步
首先我们来引入一个著名的生产者与消费者问题,来说明为什么需要进程间的同步吧。
- 生产者-消费者问题
当生产者,生产出东西投入缓冲区的时候,进行+1,当消费者从缓冲区取出的时候,进行-1。
然后来简要的说一下,+1/-1,到底是怎么进行的。
首先我们明白一点,缓冲是在Cache上的,当我们操作缓冲区的时候,实际上是这三个步骤:
(1)register = count
(2)register = register + 1
(3)count = register
当这个模型跑在单进程中,肯定是没有问题的,而如果这个任务并发地去执行在多个进程中就会出差错,因为他们访问的是同一块存储区域,就有可能出现脏读等问题。
当放入缓冲区和拿出缓冲区的程序同时执行的时候,就会出现这种问题。
就比如说,a=0,然后一个线程只执行a+1,一个线程只执行a-1,各执行100w次,结果肯定不是理想化的0.
除非加同步锁。
然后再来说一个经典的哲学家进餐的问题。
- 哲学家进餐问题
这根源的问题,也就是因为五个哲学家,也就是五个进程之间,没有进行通信而导致的。
而如果我们能做到对竞争资源在多进程之间进行使用次序的协调,就可以让并发执行的多个进程之间可以有效使用资源和相互合作。
在这里,我们称筷子本身为——临界资源。
而临界资源的含义,我们在同步的原则中会讲述。
二、进程间同步的原则
首先先呼应一下上面的问题,什么是临界资源?
临界资源指的是,一些虽然可以作为共享资源但是又无法同时被多个线程共同访问的共享资源。当有进程在使用临界资源的时候,其他进程必须依据操作系统的同步机制等待占用进程释放该共享资源才可重新竞争使用共享资源,不然就会死锁。
然后再来说一下进程间同步的原则:
- 空闲让进:资源无占用,允许使用
- 忙则等待:资源有占用,请求进程等待
- 有限等待:保证有限等待时间能够使用资源
- 让权等待:等待时,进程需要让出CPU
而让进程间同步的三个方法有:
- 消息队列
- 共享存储
- 信号量
三、线程同步
线程同步和进程同步是一样的理解。进程作为获得CPU资源的单位,而线程则是共享自己进程的资源。他们自然也需要互相保证同步,不然也会发生和进程同样的并发的问题。
让线程进行同步的方法有:
- 互斥量
- 读写锁
- 自旋锁
- 条件变量