Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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
Multithreading 在windows中控制工作线程的最佳实践(本机)?_Multithreading_Winapi_Synchronization_Worker - Fatal编程技术网

Multithreading 在windows中控制工作线程的最佳实践(本机)?

Multithreading 在windows中控制工作线程的最佳实践(本机)?,multithreading,winapi,synchronization,worker,Multithreading,Winapi,Synchronization,Worker,控制仅使用win32 API执行同一线程过程的多个工作线程的最佳实践是什么 我试过很多选择,但都做不好。我当前的代码如下所示: // thread proc DWORD WINAPI thread_proc(LPVOID param) { while(1) { WaitForSingleObject(start_event, INFINITE); // Do some work HERE // Work finished, go back

控制仅使用win32 API执行同一线程过程的多个工作线程的最佳实践是什么

我试过很多选择,但都做不好。我当前的代码如下所示:

// thread proc
DWORD WINAPI thread_proc(LPVOID param) {
    while(1) {
        WaitForSingleObject(start_event, INFINITE);

        // Do some work HERE
        // Work finished, go back to waiting for new work
    }
}

// main proc
int main(void) {
    // create enough worker threads
    CreateThread(... thread_proc...);
    CreateThread(... thread_proc...);
    ...

    // Wait for work here

    // start work by raising event
    SetEvent(start_event);
    ResetEvent(start_event);
基本上,我使用事件来启动多个工作线程,但这当然不能像预期的那样工作。若主线程在SetEvent()和ResetEvent()之间中断,工作线程将在while循环中旋转。 另一方面,使用自动重置事件对象只会释放一个等待的线程

另外,我需要主线程等待所有线程完成。我尝试了几种不同的方法,但都没能奏效。我想我刚刚开始意识到多线程编程是多么困难


编辑:语法这真是个坏主意:

1) 正如您所发现的,微观管理线程非常困难,而且容易出错。解决这个问题的办法是不要这样做

2) 在GUI线程中等待工作线程完成(或者实际上,等待任何事情)是很糟糕的。在工作线程完成时向GUI线程发送信号(例如通过PostMessage()发送)是可以的

好的,您有多个执行同一线程进程的工作线程。它们运行相同的代码,因此显然,它们对不同的数据进行操作。你能提供线程操作的数据的更多细节吗?我怀疑您最终会将任务对象/结构排队到线程池中,但我们需要更多详细信息


多线程编程并不是那么困难——只是不同而已:)最重要的细节——它与代码无关(或者,理想情况下,与任何线程实例无关),而是关于如何管理数据——数据如何分区以及数据如何移动。可悲的是,它还避免了如何不在网络上执行线程的糟糕例子:(

工作线程可以设置为低(er)优先级(GUI(主)线程具有正常优先级)。它不会真正降低速度(只要不在主线程中执行任何操作,这会让它保持忙碌状态),您的应用程序将对用户输入做出更大的响应。此外,在thread_proc()中,工作线程可能会以某种方式让步,例如,如果“找不到工作”,则等待(睡眠)一秒钟左右


另一种方法是使用APCs。

使用WaitForMultipleObjects()和bWaitAll=TRUE来等待线程句柄。然后您可以调用ResetEvent。工作线程从不终止。它们只是在初始化时创建的,每次有工作要做时都会被唤醒。等待线程句柄永远不会完成。这似乎是典型的情况“消费者-生产者模式”。Win32 API(Vista或更高版本)提供条件变量,它是实现这种模式的有用原语。如果您不熟悉该同步原语,请参阅等。在Windows上设置具有多个工作线程的生产者/消费者的一种方法是使用IO完成端口。它们基本上是多生产者多消费者队列。您可以对您可以向它们发送自定义事件,并让多个工作线程侦听您的消息。工作线程使用事件来唤醒所有线程,您可以发送N条消息。另一种方法是使用手动重置事件和原子计数器。当计数器达到线程计数时,线程使用InterlockedIncrement增加计数器,然后使用all线程已被唤醒,您可以重置事件。如果您的线程可以在事件重置之前循环回WFSO,这会涉及更多问题。我没有在GUI线程中等待。数据是一个大的字节缓冲区。每个线程都会占用一大块数据,并尝试从中查找/提取某些内容。向下投票,因为这是一个非答案。询问者要求唤醒工作线程问题的解决方案。“不要微管理线程”不是答案。你不知道提问者为什么需要这样做。此外,问题从未提到GUI线程,因此你假设了一些与问题无关的内容。投票结果也是否定的。原因与Ross Bencina相同。