简体   繁体   English

保证唤醒所有线程,每个线程仅唤醒一次

[英]guaranteeing to wake up all threads and only once per each

I found a bug in my program, that the same thread is awoke twice taking the opportunity for another thread to run, thus causing unintended behaviours. 我在程序中发现一个错误,即同一线程被唤醒两次,从而有机会运行另一个线程,从而导致了意外的行为。 It is required in my program that all threads waiting should run exactly once per turn. 在我的程序中,所有等待线程每转应准确运行一次。 This bug happens because I use semaphores to make the threads wait. 发生此错误是因为我使用信号量使线程等待。 With a semaphore initialized with count 0, every thread calls down to the semaphore at the start of its infinite loop, and the main thread calls up in a for loop NThreads (the number of threads) times. 与数0初始化的信号,每一个线程调用down在其无限循环的开始的信号,并且主线程调用up一个for循环NThreads (线程数)次。 Occasionally the same thread takes the up call twice and the problem arises. 有时,同一线程两次执行up调用,从而出现问题。

What is the way to deal with this problem properly? 如何正确处理此问题? Is using condition variables and broadcasting a way to do this? 使用条件变量并进行广播的方式吗? Will it guarantee that every thread is awoke once and only once? 是否可以保证每个线程都只能唤醒一次? What are other good ways possible? 还有哪些其他好的方法呢?

On windows, you could use WaitForMultipleObjects to select a ready thread from the threads that have not been run in the current Nthread iterations. 在Windows上,可以使用WaitForMultipleObjects从当前Nthread迭代中尚未运行的线程中选择一个就绪线程。

Each thread should have a "ready" event to signal when it is ready, and a "wake" event to wait on after it has signaled its "ready" event. 每个线程都应该有一个“就绪”事件来通知它何时准备就绪,并有一个“唤醒”事件在其发出“就绪”事件信号后等待。

At the start of your main thread loop (1st of NThreads iteration), call WaitForMultipleObjects with an array of your NThreads "ready" events. 在主线程循环的开始(NThreads迭代的第1个)开始时,请使用您的NThreads“就绪”事件数组调用WaitForMultipleObjects

Then set the "wake" event of the thread corresonding to the "ready" event returned by WaitForMultipleObjects , and remove it from the array of "ready" handles. 然后将线程的“ wake”事件设置为与WaitForMultipleObjects返回的“ ready”事件相对应,并将其从“ ready”句柄数组中删除。 That will guaranty that the thread that has already been run won't be returned by WaitForMultipleObjects on the next iteration. 这样可以确保已经运行的线程不会在下一次迭代时由WaitForMultipleObjects返回。

Repeat until the last iteration, where you will call WaitForMultipleObjects with an array of only 1 thread handle (I think this will work as if you called WaitForSingleObject). 重复直到最后一次迭代,在该迭代中,您将使用仅包含一个线程句柄的数组来调用WaitForMultipleObjects (我认为这就像您调用WaitForSingleObject一样有效)。

Then repopulate the array of NThreads "ready" events for the next new Nthreads iterations. 然后为下一个新的Nthreads迭代重新填充NThreads“就绪”事件的数组。

Well, use an array of semaphores, one for each thread. 好吧,使用一组信号量,每个线程一个。 If you want the array of threads to run once only, send one unit to each semaphore. 如果您希望线程数组仅运行一次,请向每个信号量发送一个单元。 If you want the threads to all run exactly N times, send N units to each semaphore. 如果您希望所有线程都精确运行N次,请向每个信号量发送N个单元。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM