1

如何在父线程中创建未知数量的子线程,并在 C 中使用 win32 一个一个地等待它们?
父线程的生命周期是无限的,它等待请求,如果收到任何请求,则为该请求创建一个新的子线程,例如服务器。
我正在网上搜索,但我找不到任何东西。
任何教程和信息表示赞赏。
非常感谢,祝你好运。

笔记 :

1. 例如想象一个简单的服务器:当用户向该服务器发送请求时,服务器为该用户创建一个新线程并等待该线程终止,但如果另一个用户发送另一个请求,则服务器创建另一个与该服务器完全分离的线程旧线程,然后服务器必须等待与旧线程分开的新线程终止。

2. 主线程在无限循环中扫描一个大小为常数 n 的全局数组,如果在每个数组的块中找到特定值,则运行新线程对该块的信息进行一些操作,然后在线程终止后更新块的信息。父线程生命周期是无限的,因为它有一个无限循环。

4

2 回答 2

1

也许你应该使用 WaitForMultipleObjects 函数。

http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx

于 2013-04-18T09:18:19.567 回答
1

您将创建每个线程CreateThread并将线程句柄存储在动态列表或数组中。如果您希望主线程识别线程何时终止,那么您可以调用WaitForMultipleObjects,为它提供一个包含所有线程句柄的数组。的返回值WaitForMultipleObjects将告诉您哪些线程句柄已发出信号,因此哪个线程终止。不要忘记CloseHandle最后的线程句柄。

如果您只想生成线程并且主线程不需要知道线程何时终止,那么您可以创建线程CreateThread并关闭线程句柄。当线程终止时,线程的资源将被释放。

在您的主线程中,您还需要检查是否收到客户端请求。如果您有一个可以等待事件的客户端接口,那么只需将事件添加到传递给WaitForMultipleObjects. 如果您没有像案例 2 中那样的事件,那么您可能会考虑WaitForMultipleObjects使用超时调用,以便WaitForMultipleObjects在线程终止或超时发生时返回。在这两种情况下,您的主循环都会继续运行,您可以检查是否需要生成另一个线程。

以下是使用客户端请求事件时的一些伪代码:

initialize empty list of thread data (thread handles and other data for each thread);
for(;;) {
    create an array a big enough for the request event and for all thread handles;
    a[0] = request event handle;
    a[1..n] = thread handles from the list;
    DWORD ret = WaitForMultiObjects(n+1, a, FALSE, INFINITE);
    if(ret == WAIT_OBJECT_0) {
        create thread and store it's handle and other data in the list;
    }
    else if(WAIT_OBJECT_0 + 1 <= ret  &&  ret <= WAIT_OBJECT_0 + n) {
        thread (ret - WAIT_OBJECT_0 - 1) terminated, do your cleanup and don't forget CloseHandle();
    }
    else
        error occured, should not happen;
}

如果您没有客户端请求的事件,那么您需要轮询:

initialize empty list of thread data (thread handles and other data for each thread);
for(;;) {
    create an array a big enough for the request event and for all thread handles;
    a[0..n-1] = thread handles from the list;
    DWORD ret = WaitForMultiObjects(n, a, FALSE, your desired timeout);
    if(ret != WAIT_TIMEOUT)
        ; // timeout occured, no thread terminated yet, nothing to do here
    else if(WAIT_OBJECT_0 <= ret  &&  ret < WAIT_OBJECT_0 + n) {
        thread (ret - WAIT_OBJECT_0) terminated, do your cleanup and don't forget CloseHandle();
    }
    else
        error occured, should not happen;
    // Always check for client requests, not only in case of WAIT_TIMEOUT.
    // Otherwise you might run into the situation that every time you call WaitForMultiObjects a thread ended just before the timeout occured and you only recognize it after a lot of loop runs when the last thread terminated.
    if(there is a client request) {
        create thread and store it's handle and other data in the list;
    }
}

如果您不需要为每个线程存储额外的数据,那么您可以只存储线程句柄,并且可能已经将它们存储在一个大数组中。因此,您可以消除从线程句柄列表构建数组的步骤。

于 2013-04-18T09:21:11.190 回答