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