Linux中posix线程的pthread_cond_wait函数为何使用while循环

来源:互联网 发布:apple pencil推荐软件 编辑:程序博客网 时间:2024/05/20 06:31

关于pthread_cond_wait函数为何需要使用while循环,或者为何不使用if条件判断问题,经过Google后发现网上有不少已说明,这里给出自己的说明:

该函数的定义,可参考http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html,有详细的说明,把其中一段拿出来开始谈谈为何需要使用while循环:

If a signal is delivered to a thread waiting for a condition variable, upon return from the signal handler the thread resumes waiting for the condition variable as if it was not interrupted, or it returns zero due to spurious wakeup.

这里提到了两个原因:(1)it was not interrupted; (2)due to spurious wakeup.可能会使该函数的使用无法正常得到预期结果,原因(1)很显然是因为一些中断或者非程序猿因素而导致的返回信号无法被正确接受,原因(2)提到了一个新名词,spurious wakeup,技术人员都叫其为“惊群效应”,关于其定义,可参考http://en.wikipedia.org/wiki/Spurious_wakeup,description中有一句是“to verify that the condition is indeed true after the thread has finished waiting”,这句话的意思就是为了证实等待的线程是在是在满足条件后重新运行。由于pthread_cond_wait函数是在另外一个线程中通过pthread_cond_singnal或pthread_cond_broadcast函数激活,这两种激活方式可以唤醒所以在等待该条件变量的线程,而如果只能有一个线程进入临界区,也就是只能有一个线程进行处理,此时必须重复进行条件判定:

thread 1:

pthread_mutex_lock(&mutex);

while(a<=b)

{pthread_cond_wait(&cond,&mutex);}

pthread_mutex_unlock(&mutex);


thread2:

pthread_mutex_lock(&mutex);

/*a,b的一些操作后*/

if(a>b)

{pthread_cond_singal(&cond);}

pthread_mutex_unlock(&mutex);

spurious wakeup中提到条件变量可能会在其处于等待状态时满足,即使没有任何signal信号到来,也就是说thread1中的a<=b可能会满足条件,但此时并没有属于自己的signal唤醒信号,而是由于“惊群效应”,而且在多线程中,这种现象可能会不断地出现,故而需要反复循环判定,来确保条件的满足。惊群效应主要出现在posix线程池和多线程api中,上问题到的pthread_cond_signal其实并不会引起惊群效应,只是有时为了简便,一些多处理系统的内核会这么做而已。

总之,使用while可能从逻辑上讲会降低程序执行效率,但从内部线程之间的运行机制来看,是一种较为稳妥并安全的方式,so,“建议”使用while 循环!


0 0
原创粉丝点击