先介绍一下pthread_cond_wait()函数的调用过程,wait函数首先对互斥对象进行解锁,然后等待条件的发生,即等待pthread_cond_signal()或pthread_cond_broadcast()函数的调用,然后wait函数返回,返回时对互斥对象进行加锁。
那么在调用pthread_cond_wait()函数之前为什么要对条件变量进行加锁呢?
原因很简单,如果条件不成立我们就进入阻塞,在进入阻塞这个期间,如果条件变量改变了的话,那我们就漏掉了这个条件(from APUE)。这句话不是很好理解,假如我们有thread1,thread2对全局共享变量num++,当num的值为100时,唤醒thread3,当thread3进入阻塞期间时,num值为100,此时thread1或thread2向条件变量发送信号,但是由于thread3并没有真正的进入阻塞,而是处于进入阻塞这个状态。结果,thread3便遗漏了这个条件。因此,在使用条件变量时,一定要让pthread_cond_wait()完成阻塞,所以我们要首先用互斥对象锁住条件变量,让其他线程无法使用条件变量。
还有一个问题,在使用条件变量时,为什么在让pthread_cond_wait()在while循环内,用if不可以么?
答案是不可以的,具体原因在于等待线程可能会别莫名奇妙的其他信号唤醒,因此在每次被唤醒时,我们都要检查唤醒的条件。