Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows中正确的线程同步对象是什么,它允许一个线程等待另一个线程取消阻止它?_Windows_Multithreading_Events_Synchronization - Fatal编程技术网

Windows中正确的线程同步对象是什么,它允许一个线程等待另一个线程取消阻止它?

Windows中正确的线程同步对象是什么,它允许一个线程等待另一个线程取消阻止它?,windows,multithreading,events,synchronization,Windows,Multithreading,Events,Synchronization,我有一个在Windows下运行的Delphi应用程序,它需要阻塞,直到另一个线程交付数据。换句话说,我需要等待一个同步对象,我可以从一个特定线程将其置于无信号状态,就好像另一个线程拥有该对象的所有权一样,这样当我调用WaitFor()时,线程会阻塞,直到另一个线程将其解锁(有多个潜在线程可以解除阻止,并且事先不知道是哪个线程)。请注意,所有线程都可以访问共享数据区域,因此访问公共同步对象不是问题 我认为事件是正确的选择,直到我阅读了Raymond Chen关于PulseEvent()问题的这篇令

我有一个在Windows下运行的Delphi应用程序,它需要阻塞,直到另一个线程交付数据。换句话说,我需要等待一个同步对象,我可以从一个特定线程将其置于无信号状态,就好像另一个线程拥有该对象的所有权一样,这样当我调用WaitFor()时,线程会阻塞,直到另一个线程将其解锁(有多个潜在线程可以解除阻止,并且事先不知道是哪个线程)。请注意,所有线程都可以访问共享数据区域,因此访问公共同步对象不是问题

我认为事件是正确的选择,直到我阅读了Raymond Chen关于PulseEvent()问题的这篇令人不安的博文:


实现此结果的正确同步技术是什么?如果您有一个指向Delphi或C/C++示例的链接,那就太好了。

事件非常好,只是不要使用PulseEvent。Microsoft不仅毫无希望地破坏了实现,而且它的使用因固有的竞争条件而变得复杂。如果事件恰好发生在如果事件上的线程阻塞,事件将丢失。请改用手动重置事件

阻止:

B1)将事件设置为阻塞

B2)检查以确保事件尚未发生,并确保要阻止它。如有必要,将事件放在共享数据结构中,唤醒我们的线程会注意到它

B3)封锁事件

唤醒:

W1)更新共享数据以反映事件已发生的事实

W2)取消阻止事件。如有必要,遍历共享数据结构并取消阻止所有与刚刚发生的事件相关的事件

这里没有比赛条件。如果事件发生在B1或B2之后,但在B3之前,B3中的块实际上不会阻塞,因为W2将解除阻塞。如果事件已经发生在W1之前,线程将永远不会阻塞,因为B2将看到W1的效果,我们将永远不会到达B3


在大多数情况下,操作B2和W2需要在持有由处理此类事件的所有线程共享的锁的同时执行。

只需使用自动重置事件即可。请参见CreateEvent函数的参数。需要等待的每个线程都需要一个事件。只需调用SetEvent,而不需要其他函数,如PulseEvent或ResetEvent。WaitFor将自动重置事件。如果在调用WaitFor之前已设置了事件,它将立即返回,并重置事件。

您认为为什么要在SetEvent上使用PulseEvent?@Logan Capaldo。我不。我只是对事件不够熟悉,不知道PulseEvent不需要使用它们。下面大卫的回答帮助我理解了他们。谢谢@David Schwartz。关键部分是否足以保护B2和W2操作?此外,任何关于关闭相关线程的线程或应用程序终止提示(除了确保所有事件都未被阻止之外)?@RobertOschler是的,关键部分可以。不要关闭线程。只需对线程进行编码,以便它们在没有工作要做时自动关闭。(并安排一些事情,使它们在没有工作要做的时候没有工作要做。)一些线程来自DirectShow筛选器和筛选器图形操作,因此我无法始终控制它们如何关闭。如果你有任何DirectShow的具体建议,我很乐意听听。