为什么phread_cond_wait要加while?
江东橘子 2011-07-28 05:00:05 说加while的目的是只让一个线程唤醒,其他的都等待
下面这段绿色的是小弟从网上拷贝而来的,看了一下,还是有个地方不明白:
pthread_mutex_lock(&mut);
while (x <= y) {
pthread_cond_wait(&cond, &mut);
}
/* operate on x and y */
pthread_mutex_unlock(&mut);
和: pthread_mutex_lock(&mut);
/* modify x and y */
if (x > y) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mut);
其实函数的执行过程非常简单,在第一个线程执行到pthread_cond_wait(&cond,&mut)时,此时如果X<=Y,则此函数就将mut互斥量解锁,再将cond条件变量加锁,此时第一个线程挂起(不占用任何CPU周期)。
而在第二个线程中,本来因为mut被第一个线程锁住而阻塞,此时因为mut已经释放,所以可以获得锁mut,并且进行修改X和Y的值,在修改之后,一个IF语句判定是不是X>Y,如果是,则此时pthread_cond_signal()函数会唤醒第一个线程,并在下一句中释放互斥量mut。然后第一个线程开始从pthread_cond_wait()执行,首先要再次锁mut,如果锁成功,再进行条件的判断(至于为什么用WHILE,即在被唤醒之后还要再判断,后面有原因分析),如果满足条件,则被唤醒进行处理,最后释放互斥量mut。
至于为什么在被唤醒之后还要再次进行条件判断(即为什么要使用while循环来判断条件),是因为可能有“惊群效应”。有人觉得此处既然是被唤醒的,肯定是满足条件了,其实不然。如果是多个线程都在等待这个条件,而同时只能有一个线程进行处理,此时就必须要再次条件判断,以使只有一个线程进入临界区处理。
thread_cond_signal在多处理器上可能同时唤醒多个线程,当你只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续 wait,while循环的意义就体现在这里了,而且规范要求pthread_cond_signal至少唤醒一个pthread_cond_wait上的线程,其实有些实现为了简单在单处理器上也会唤醒多个线程.
2,某些应用,如线程池,pthread_cond_broadcast唤醒全部线程,但我们通常只需要一部分
线程去做执行任务,所以其它的线程需要继续wait.所以强烈推荐此处使用while循环.
其实说白了很简单,就是pthread_cond_signal()也可能唤醒多个线程,而如果你同时只允许一个线程访问的话,就必须要使用while来进行条件判断,以保证临界区内只有一个线程在处理。
问题1:假设有10个线程都在pthread_cond_wait(&cond, &mut);当改变x,y的大小有,调用了pthread_cond_signal(&cond);
那么这10个线程都被唤醒了(应为上文说到规范要求pthread_cond_signal至少唤醒一个pthread_cond_wait上的线程);然后程序循环判定while(x<=y),这时x>y,那么这10个线程都跳过while循环,执行下面的代码了。但是上面解释说是唤醒了一个线程,其他9个线程将继续pthread_cond_wait(&cond, &mut)?
问题2:由问题1而来。当10个线程都被唤醒了,那么调用10次pthread_cond_wait(&cond, &mut).但是调用一次pthread_cond_wait(&cond, &mut)时,就解锁mut;
既然mut解锁了,那么其他9次mut怎么办