leg*_*s2k 47 multithreading synchronization operating-system mutex condition-variable
我确定互斥是不够的,这就是条件变量概念存在的原因; 但它打败了我,当一个条件变量必不可少时,我无法用一个具体的场景来说服自己.
条件变量,互斥锁和锁定问题的接受答案之间的区别是条件变量是a
锁定"信号"机制.当线程需要等待资源变得可用时使用它.线程可以在CV上"等待",然后资源生成器可以"发出信号"变量,在这种情况下,等待CV的线程会得到通知并可以继续执行
我感到困惑的是,一个线程也可以在互斥锁上等待,当它被发出信号时,只是意味着该变量现在可用,为什么我需要一个条件变量?
PS:此外,无论如何,需要一个互斥锁来保护条件变量,当我的视力更加偏向于看不到条件变量的目的时.
slo*_*elj 30
即使您可以按照您描述的方式使用它们,但互斥锁并非设计用作通知/同步机制.它们旨在提供对共享资源的互斥访问.使用互斥锁发出信号是很尴尬的,我想看起来像这样(Thread2由Thread2发出信号):
线程1:
while(1) {
lock(mutex); // Blocks waiting for notification from Thread2
... // do work after notification is received
unlock(mutex); // Tells Thread2 we are done
}
Run Code Online (Sandbox Code Playgroud)
线程2:
while(1) {
... // do the work that precedes notification
unlock(mutex); // unblocks Thread1
lock(mutex); // lock the mutex so Thread1 will block again
}
Run Code Online (Sandbox Code Playgroud)
这有几个问题:
这两个问题并不轻微,事实上,它们都是主要的设计缺陷和潜在的错误.这两个问题的根源是要求在同一个线程中锁定和解锁互斥锁.那么你如何避免上述问题呢?使用条件变量!
顺便说一句,如果您的同步需求非常简单,您可以使用一个简单的旧信号量,避免条件变量的额外复杂性.
Mutex用于独占访问共享资源,而条件变量用于等待条件为真.人们可能认为他们可以在没有内核支持的情况下实现条件变量.人们可能提出的一个常见解决方案是"flag + mutex"就像:
lock(mutex)
while (!flag) {
sleep(100);
}
unlock(mutex)
do_something_on_flag_set();
Run Code Online (Sandbox Code Playgroud)
但它永远不会工作,因为你在等待期间永远不会释放互斥锁,没有其他人可以以线程安全的方式设置标志.这就是为什么我们需要条件变量,当你等待一个条件变量时,你的线程不会保持相关的互斥锁,直到它被发出信号.
您需要条件变量,与互斥体一起使用(每个 cond.var. 属于一个互斥体),以发出从一个线程到另一个线程的状态(条件)变化信号。这个想法是线程可以等待直到某些条件成立。这些条件是特定于程序的(即“队列为空”、“矩阵很大”、“某些资源几乎耗尽”、“某些计算步骤已完成”等)。互斥体可能有几个相关的条件变量。您需要条件变量,因为此类条件可能并不总是简单地表达为“互斥体被锁定”(因此您需要将条件的更改广播到其他线程)。
阅读一些好的 posix 线程教程,例如本教程或那个或那个教程。更好的是,阅读一本好的 pthread 书籍。看到这个问题。
PS 并行和线程是很难掌握的概念。花时间阅读、尝试、再阅读。
我也在考虑这个问题,最重要的信息,我到处都缺少的是,互斥量只能在一个线程中拥有(和更改).因此,如果您有一个生产者和更多的消费者,生产者将不得不等待互斥产生.与cond.他可以随时生产的变量.
归档时间: |
|
查看次数: |
31344 次 |
最近记录: |