近来在项目中用到条件变量和信号量作同步时,这一块一直都有了解,但也一直没有总结,此次总结一下,给你们提供点参考,也给本身留点记念。html
首先,关于信号量和条件变量的概念能够自行查看APUE,我这直接把APUE中的代码拿过来对比;spa
条件变量的使用:线程
#include <pthread.h> struct msg { struct msg *m_next; /* ... more stuff here ... */ }; struct msg *workq; pthread_cond_t qready = PTHREAD_COND_INITIALIZER; pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER; void process_msg(void) { struct msg *mp; for (;;) { pthread_mutex_lock(&qlock); while (workq == NULL) pthread_cond_wait(&qready, &qlock); mp = workq; workq = mp->m_next; pthread_mutex_unlock(&qlock); /* now process the message mp */ } } void enqueue_msg(struct msg *mp) { pthread_mutex_lock(&qlock); mp->m_next = workq; workq = mp; pthread_mutex_unlock(&qlock); pthread_cond_signal(&qready); }
其中最后在调用也能够按照下面格式调用,两种各有优劣,具体能够参考:http://www.javashuo.com/article/p-tzdowvkx-n.htmlcode
pthread_mutex_lock(&qlock); mp->m_next = workq; workq = mp;
pthread_cond_signal
pthread_mutex_unlock
条件变量和信号量的区别:htm
(1)使用条件变量能够一次唤醒全部等待者,而这个信号量没有的功能,感受是最大区别。blog
(2)信号量是有一个值(状态的),而条件变量是没有的,没有地方记录唤醒(发送信号)过多少次,也没有地方记录唤醒线程(wait返回)过多少次。从实现上来讲一个信号量能够是用mutex + counter + condition variable实现的。由于信号量有一个状态,若是想精准的同步,那么信号量可能会有特殊的地方。信号量能够解决条件变量中存在的唤醒丢失问题。进程
(3)在Posix.1基本原理一文声称,有了互斥锁和条件变量还提供信号量的缘由是:“本标准提供信号量的而主要目的是提供一种进程间同步的方式;这些进程可能共享也可能不共享内存区。互斥锁和条件变量是做为线程间的同步机制说明的;这些线程老是共享(某个)内存区。这二者都是已普遍使用了多年的同步方式。每组原语都特别适合于特定的问题”。尽管信号量的意图在于进程间同步,互斥锁和条件变量的意图在于线程间同步,可是信号量也可用于线程间,互斥锁和条件变量也可用于进程间。应当根据实际的状况进行决定。信号量最有用的场景是用以指明可用资源的数量。内存
经典的一句话:资源
互斥量是信号量的一种特例,互斥量的本质是一把锁。A mutex is basically a lock that we set (lock) before accessing a shared resource and release (unlock) when we're doneget