当前位置:  开发笔记 > 编程语言 > 正文

pthread_cond_wait与信号量

如何解决《pthread_cond_wait与信号量》经验,为你挑选了3个好方法。

使用pthread_cond_wait或使用信号量的优点/缺点是什么?我正在等待这样的状态变化:

pthread_mutex_lock(&cam->video_lock);
while(cam->status == WAIT_DISPLAY) {
    pthread_cond_wait(&cam->video_cond, &cam->video_lock);
}
pthread_mutex_unlock(&cam->video_lock);

使用正确初始化的信号量,我想我可以这样做:

while(cam->status == WAIT_DISPLAY) {
    sem_wait(&some_semaphore);
}

每种方法的优缺点是什么?



1> Steve Jessop..:

信号量适合生产者 - 消费者模型,尽管它有其他用途.您的程序逻辑负责确保为等待次数提供正确数量的帖子.如果你发布了一个信号量而没有人在等待它,那么当他们等待时他们会立即继续.如果您的问题可以用信号量的计数值来解释,那么用信号量解决它应该很容易.

条件变量在某些方面更宽容一些.例如,您可以使用cond_broadcast唤醒所有服务员,而生产者不知道有多少服务员.如果你在没有人等待的情况下cond_signal condvar那么没有任何反应.如果您不知道是否会有听众感兴趣,这很好.这也是为什么听众应该总是在等待之前用互斥锁检查状态 - 如果他们不这样做,那么他们可能会错过一个信号而不会在下一个信号唤醒之前(可能永远不会).

因此,条件变量适用于通知感兴趣的各方状态已发生变化:您获取互斥锁,更改状态,发信号(或广播)condvar并释放互斥锁.如果这描述了您的问题,那么您就处于condvar领域.如果不同的听众对不同的状态感兴趣,你可以直接播放,然后他们每个人都会醒来,弄清楚他们是否找到了他们想要的状态,如果不再等.

用互斥量和信号量尝试这种事情确实非常粗糙.当您想要获取互斥锁,检查某个状态,然后等待信号量进行更改时,就会出现问题.除非你可以原子地释放互斥锁并等待信号量(在pthreads中你不能),否则你最终会在持有互斥锁的同时等待信号量.这会阻止互斥锁,这意味着其他人无法接受它来进行您关心的更改.因此,您将尝试以某种方式添加另一个互斥锁,具体取决于您的具体要求.也许是另一个信号量.结果通常是错误的代码与有害的竞争条件.

条件变量可以解决此问题,因为调用cond_wait会自动释放互斥锁,释放它以供其他人使用.在cond_wait返回之前重新获得互斥锁.

IIRC可以仅使用信号量来实现一种condvar,但是如果要实现与condvar一起使用的互斥锁需要有trylock,那么这是一个严重的头脑,并且定时等待已经结束.不建议.因此,不要假设您可以使用信号量完成任何与condvar相关的操作.当然,互斥量可以具有信号量不足的好行为,主要是优先级反转避免.



2> freespace..:

条件允许你做一些信号量不会做的事情.

例如,假设您有一些代码需要一个名为的互斥锁m.然而,它需要等到其他一些线程完成它们的任务,所以它等待一个被调用的信号量s.现在任何需要的线程都m被阻止运行,即使m正在等待的线程s.可以使用条件解决这些情况.当您等待条件时,当前保持的互斥锁被释放,因此其他线程可以获取互斥锁.回到我们的例子,并假设使用条件c而不是s.我们的线程现在获取m,然后有条件等待c.这将释放,m以便其他线程可以继续.什么时候c可用,m 被重新获取,我们的原始线程可以继续愉快地继续.

条件变量还允许您让所有等待条件变量的线程继续进行pthread_cond_broadcast.此外,它还允许您执行定时等待,这样您就不会永远等待.

当然,有时你不需要条件变量,因此根据你的要求,一个或另一个可能会更好.


这是一个很好的答案.为了添加到描述中,相对于所描述的互斥锁和信号量的组合,条件是唯一的是条件以原子方式操纵互斥锁/信号量对!!

3> Blaisorblade..:

第二个片段是活泼的,不要这样做.

其他答案对相对优点进行了很好的讨论; 我只想补充说,这pthread_cond_broadcast是条件变量的明显优势.

除此之外,我更习惯于为此调整变量,因为它们是您在Java中使用的变量,即使它们可以帮助您在检查共享标志时避免竞争.

实际上,在第二个片段中,您没有任何锁定保护读取cam-> status,因此可以通过数据竞争访问它.大多数平台都会让你在这个特定的例子中侥幸逃脱,但它有未定义的语义,POSIX和下一个C/C++标准的内存模型.

事实上,如果另一个线程分配一个新的凸轮结构并覆盖凸轮,则可能出现真正的竞争条件; 等待线程可能会看到'cam'指针的更新而没有看到cam-> status的初始化.事实上,在这种情况下,第二个片段是在寻求麻烦.

http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有