如何强制线程严格按顺序工作?

2023-12-30

我正在编写一个多线程控制台应用程序,使用 WinAPI 的关键部分作为同步机制。我需要创建5个线程,每个线程都有自己的字符串由线程显示。线程应该按顺序一一输出它们的字符串。

所以,我有线程函数:

void thread_routine(void* data)
{
    std::string* st = (std::string*)data;
    while(1)
    {
        /* enter critical section */
        std::cout << st; // not exactly that way, but I hope that you understood what I've meant.
        Sleep(100);
        /* leave critical section */
    }
}

而在我的main()

for(int i = 0; i < 10; ++i)
    _beginthread(thread_routine, 0, strings[i]);

好吧,我期待看到类似的东西[o1]:

1) First thread
2) Second thread
3) Third thread
4) Fourth thread
5) Fifth thread
... and so on

但我没有看到这样的输出[o2]:

1) First thread
1) First thread
3) Third thread
2) Second thread
5) Fifth thread
... and so on

我清楚地理解发生了什么:线程通过关键部分的顺序是未知的,因此该部分将被随机的部分捕获,但我需要同步我的线程以获得类似的输出[o1]。那我该怎么办呢?有什么模式吗?


临界区并不是解决这个问题的方法。临界区只不过是一个互斥设备。其目的是确保在给定时间只有一个线程可以执行特定的代码片段。它并非旨在用于测序,也不是特别适合该任务。问题是你不能wait在关键部分上而不获取它。

考虑这样一种情况,线程 B 必须等待线程 A 完成才能继续其工作。如果您使用关键部分(将其称为cs1),那么你必须确保线程 A 在线程 B 尝试获取它之前获取它。这意味着您必须 100% 确定线程 A 开始执行并获取临界区,然后线程 B 才能执行潜在地获取临界区。

事件对象 http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655%28v=vs.85%29.aspx另一方面,允许您等待事件或在事件已经发生时继续。因此线程 B 可以在线程 A 启动之前等待该事件。它将等待,直到线程 A(或某人)设置事件。您描述的问题(线程 B 需要等待某些事件发生)是exactly事件对象旨在解决的问题类型。

假设有 3 个线程并行处理一段时间,但在某些时候需要等待其他事件发生,您需要编写代码来创建并等待事件。简要地:

HANDLE event1_done = CreateEvent(...);
HANDLE event2_done = CreateEvent(...);
HANDLE event3_done = CreateEvent(...);

所有事件都是手动重置的,并且它们的初始状态没有信号。

主线程启动三个事件。然后等待第三个完成:

WaitForSingleObject(event3_done, INFINITE);

各个线程进行处理并等待各自的事件。当然,线程 1 不会等待。它只是这样做:

// thread 1
// do processing
// then signal that it's finished
SetEvent(event1_done);

线程 2 进行处理并等待event1_done,然后设置event2_done:

// thread 2
// do processing
// wait for the first thread to complete
WaitForSingleObject(event1_done, INFINITE);
// do whatever
// and then signal that it's done
SetEvent(event2_done);

线程 3 与线程 2 类似;只是事件名称发生了变化。

此方法与使用临界区的区别在于多个线程可能正在等待同一个事件对象。当该事件设置时,all等待该对象的线程被释放。如果您只想释放其中一个,那么您可以使用自动重置事件。

另请注意,如果您想重复使用这些事件,则需要重置它们(调用ResetEvent)。当你这样做时,这取决于你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何强制线程严格按顺序工作? 的相关文章

随机推荐