为什么phread_cond_wait要加while?
时间:2011-07-28
来源:互联网
说加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怎么办
下面这段绿色的是小弟从网上拷贝而来的,看了一下,还是有个地方不明白:
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怎么办
作者: michael1112 发布时间: 2011-07-28
1、10个线程不可能都从pthread_cond_wait中返回
因为返回前需要重新加锁,而只能有一个加锁成功
因为返回前需要重新加锁,而只能有一个加锁成功
作者: justkk 发布时间: 2011-07-28
hi, 看了你的问题,我发现我也没有仔细思考过这个问题
仔细google了一下,有了一下理解:
首先,我发现使用while的原因并不是因为好些文章所说的,是为了只唤醒一个线程,明显这是不可能的,的确pthread_cond_wait返回前需要重新加锁,但是只要条件成立,多个线程还是可能被唤醒
实际上,while的使用是因为"假唤醒"的问题,即,线程可能不是被cond_signal或cond_broadcast唤醒的,而是被中断换醒了
那为什么不能fix这样的问题,而是需要调用者来完成呢,http://vladimir_prus.blogspot.com/2005/07/spurious-wakeups.html 这篇文章给了非常详细的解释
希望对你能有帮助
欢迎大家拍砖(:
仔细google了一下,有了一下理解:
首先,我发现使用while的原因并不是因为好些文章所说的,是为了只唤醒一个线程,明显这是不可能的,的确pthread_cond_wait返回前需要重新加锁,但是只要条件成立,多个线程还是可能被唤醒
实际上,while的使用是因为"假唤醒"的问题,即,线程可能不是被cond_signal或cond_broadcast唤醒的,而是被中断换醒了
那为什么不能fix这样的问题,而是需要调用者来完成呢,http://vladimir_prus.blogspot.com/2005/07/spurious-wakeups.html 这篇文章给了非常详细的解释
希望对你能有帮助
欢迎大家拍砖(:
作者: woso 发布时间: 2011-07-28
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28