生产者消费者问题就是一个著名的线程同步问题,该问题描述如下:有一个生产者
在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并
发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放
入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者
之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者
向一个已经放入产品的缓冲区中再次投放产品。
(1)互斥锁:只有一个生产者和一个消费者,我们这个时候就可以把缓冲区设置
为一个互斥量,一次要么生产者要么消费者霸占它。
(2)读写锁:只有一个生产者或者多个生产者问题,有多个消费者, 我们这个时
候就可以把为生产者设置一个写锁,为每个消费者设置一个读锁。
当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程
都会被阻塞。当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都
可以得到访问权,但是如果线程希望以写模式对此锁进行加锁,它必须阻塞直到所
有的线程释放读锁。
(3)条件变量:只有一个生产者和一个消费者(其实也适用于多个生产者和消费者)
, 我们这个时候就可以把缓冲区设置为一个互斥量,一次要么生产者要么消费者霸
占它。但接下来处理方式与互斥量有所不同:假如生产者成功占据锁(缓冲区),这
时它不能马上开始往里面生产东西,要先判断缓冲区是不是满的,如果缓冲区满了,
那么生产者就会把自己放到等待条件的线程列表上,然后对互斥量进行解锁,这是一
个原子操作。如果缓冲区不满则可以生产产品,然后给消费者发送notempty信号,表
示缓冲区有产品了。然后解锁互斥量。假如是消费者成功占据锁(缓冲区),同样它
要检查缓冲区是不是空的,如果空,那么消费者就会把自己放到等待条件的线程列表
上,然后对互斥量进行解锁。如果不空,消费者开始工作,然后给生产者发送nofull
信号, 表示缓冲区有位置可以生产了,你快生产吧。然后解锁互斥量。就这样,生产
者消费者和谐同步工作着。
在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并
发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放
入一个缓冲区中,消费者可以从缓冲区中取走产品进行消费,显然生产者和消费者
之间必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者
向一个已经放入产品的缓冲区中再次投放产品。
(1)互斥锁:只有一个生产者和一个消费者,我们这个时候就可以把缓冲区设置
为一个互斥量,一次要么生产者要么消费者霸占它。
(2)读写锁:只有一个生产者或者多个生产者问题,有多个消费者, 我们这个时
候就可以把为生产者设置一个写锁,为每个消费者设置一个读锁。
当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程
都会被阻塞。当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都
可以得到访问权,但是如果线程希望以写模式对此锁进行加锁,它必须阻塞直到所
有的线程释放读锁。
(3)条件变量:只有一个生产者和一个消费者(其实也适用于多个生产者和消费者)
, 我们这个时候就可以把缓冲区设置为一个互斥量,一次要么生产者要么消费者霸
占它。但接下来处理方式与互斥量有所不同:假如生产者成功占据锁(缓冲区),这
时它不能马上开始往里面生产东西,要先判断缓冲区是不是满的,如果缓冲区满了,
那么生产者就会把自己放到等待条件的线程列表上,然后对互斥量进行解锁,这是一
个原子操作。如果缓冲区不满则可以生产产品,然后给消费者发送notempty信号,表
示缓冲区有产品了。然后解锁互斥量。假如是消费者成功占据锁(缓冲区),同样它
要检查缓冲区是不是空的,如果空,那么消费者就会把自己放到等待条件的线程列表
上,然后对互斥量进行解锁。如果不空,消费者开始工作,然后给生产者发送nofull
信号, 表示缓冲区有位置可以生产了,你快生产吧。然后解锁互斥量。就这样,生产
者消费者和谐同步工作着。