一、 线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。在pthread库中通过条件变量(Condition Variable)来阻塞等待某个条件,或者唤醒等待这个条件的线程。Condition Variablepthread_cond_t类型的变量表,可以这样初始化和销毁:

wKioL1cYeM2whfMMAAA72IoCNxU075.jpg

返回值:成功返回0,失败返回错误号。

一个Condition Variable总是和一个Mutex搭配使用的。一个线程可以调用pthread_cond_wait在一个Condition Variable上阻塞等待,这个函数做以下三步操作: 

1. 释放Mutex

2. 阻塞等待

3. 当被唤醒时,重新获得Mutex并返回  

pthread_cond_timedwait函数还有一个额外的参数可以设定等待超时,如果到达了abstime所指定的时刻仍然没有别的线程来唤醒当前线程,就返回ETIMEDOUT。一个线程可以调用pthread_cond_signal唤醒在某个Condition Variable上等待的另一个线程,也可以调用pthread_cond_broadcast唤醒在这Condition Variable上等待的所有线程。

二、生产者--消费者问题

本例中使用带头单链表实现生产者消费者之间的场所,使用尾插头删的功能。如下为只有一个消费者,一个生产者。生产者实现插入节点,消费者实现删除节点。需要条件变量与互斥锁结合使用。

代码如下:

wKioL1caJZrQ_xzkAACbnOPzC84976.jpg

wKiom1caJNbQzwzHAABd9D0dHUk208.jpg

wKioL1caJZuhWIvrAAB_IVVwB9g464.jpg

wKioL1caJZvy2D49AACHd9WXrcM095.jpg

其运行结果如下:

wKiom1caJNiDW_UxAABSiMokI-c199.jpg

改为多线程:也就是多消费者,多生产者。需要实现,消费者与消费者之间互斥,生产者与生产者之间互斥,消费者与生产者之间互斥。代码如下:

wKiom1caJTzxUNSOAABcYA2Qpx0341.jpg

wKioL1caJgDDbv8NAABk4WxoxKA323.jpg

其运行结果如下:

wKiom1caJTzB1_NLAABW9RWHLp4954.jpg

总结:在互斥的基础之上实现了同步,不仅解决了死锁的问题,而且使线程间的通信更加的高效。