互斥量(mutex)从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁以后,任何其他试图再次对互斥锁加锁的线程将会阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥锁加锁,其他线程将会看到互斥锁依然被锁住,只能回去再次等待它重新变为可用。
条件变量(cond)是在多线程程序中用来实现”等待–》唤醒”逻辑常用的方法。条件变量利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使“条件成立”。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。线程在改变条件状态前必须首先锁住互斥量,函数pthread_cond_wait把自己放到等待条件的线程列表上,然后对互斥锁解锁(这两个操作是原子操作)。在函数返回时,互斥量再次被锁住。
第一点,首先我们要理解条件变量的作用是在等待某个条件达成时自身要进行睡眠或阻塞,避免忙等待带来的不必要消耗,所以条件变量的作用在于同步。条件变量这个变量其实本身不包含条件信息,条件的判断不在pthread_cond_wait函数功能中,而需要外面进行条件判断。这个条件通常是多个线程或进程的共享变量,这样就很清楚了,对于共享变量很可能产生竞争条件尤其还对共享变量加了条件限制,所以从这个角度看,必须对共享变量加上互斥锁。
第二点,pthread_cond_wait这个函数的过程我们必须了解,首先对互斥锁进行解锁(条件判断不属于函数的功能),解锁之后自身睡眠等待条件达成,注意这时候函数并未返回,因为还缺少一步,待条件完成后重新加锁。pthread_cond_wait提供的重要功能是保证这两个操作一定是原子操作不可分割。试想一下,如果进程A调用了pthread_cond_wait,先进行了解锁,这时候由于进程A时间片到期,轮换到进程B,进程B一直想要这把锁,现在终于拿到了,它干完了事情,调用pthread_cond_signal想唤醒A但是A并未完成睡眠等待条件达成,所以这个唤醒信号就丢失了。
参考:http://blog.csdn.net/championhengyi/article/details/52120065