由于MAXIMUM_WAIT_OBJECTS
函数的WaitForMultipleObjects
限制,我试图编写自己的“等待线程”函数,但没有得到它的工作。你能给我一个提示吗,怎么做?
这是我的“等待线程”功能:
void WaitForThreads(std::set<HANDLE>& handles)
{
for (int i = 0; i < SECONDSTOWAIT; i++)
{
// erase idiom
for (std::set<HANDLE>::iterator it = handles.begin();
it != handles.end();)
{
if (WaitForSingleObject(*it, 0) == WAIT_OBJECT_0)
handles.erase(it++);
else
++it;
}
if (!handles.size())
// all threads terminated
return;
Sleep(1000);
}
// handles.size() threads still running
handles.clear();
}
只要线程运行WaitForSingleObject
返回WAIT_TIMEOUT
,但当线程终止时,返回值为WAIT_FAILED
而不是WAIT_OBJECT_0
。我想线程句柄不再有效,因为GetLastError
返回ERROR_INVALID_HANDLE
。
MSDN建议采用以下解决方案:
- 创建一个线程以等待MAXIMUM_WAIT_OBJECTS句柄,然后等待该线程加上其他句柄。使用此技术将句柄分成MAXIMUM_WAIT_OBJECTS组。
- 调用RegisterWaitForSingleObject在每个句柄上等待。来自线程池的等待线程在MAXIMUM_WAIT_OBJECTS注册的对象上等待,并在发出对象信号或超时间隔到期后分配工作线程。
但在我看来,两者都是太费力了。
修改
使用MFC函数AfxBeginThread
创建线程。返回的CWinThread
指针仅用于获取关联的句柄。
CWinThread* thread = AfxBeginThread(LANAbfrage, par);
if ((*thread).m_hThread)
{
threads.insert((*thread).m_hThread);
helper::setStatus("%u LAN Threads active", threads.size());
}
else
theVar->TraceN("Error: Can not create thread");
答案 0 :(得分:3)
但在我看来,两者都是太费力了。
如果您希望它与等待句柄一起使用,那就是您必须要做的事情。但是,如果您需要的是在所有线程完成之前阻塞的东西,您可以使用Semaphore或Synchronization Barrier。
答案 1 :(得分:1)
使用answer from Jim Mischel我找到了解决方案。 Semaphore Objects可以解决两个问题:
这是一个小而独立的例子:
#include <iostream>
#include <vector>
#include <windows.h>
static const LONG SEMCOUNT = 3;
DWORD CALLBACK ThreadProc(void* vptr)
{
HANDLE* sem = (HANDLE*)vptr;
Sleep(10000);
ReleaseSemaphore(*sem, 1, NULL);
return 0;
}
int main()
{
HANDLE semh = CreateSemaphore(NULL, SEMCOUNT, SEMCOUNT, 0);
// create 10 threads, but only SEMCOUNT threads run at once
for (int i = 0; i < 10; i++)
{
DWORD id;
WaitForSingleObject(semh, INFINITE);
HANDLE h = CreateThread(NULL, 0, ThreadProc, (void*)&semh, 0, &id);
if (!h)
CloseHandle(h);
}
// wait until all threads have released the semaphore
for (LONG j = 0; j < SEMCOUNT; j++)
{
WaitForSingleObject(semh, INFINITE);
std::cout << "Semaphore count = " << j << std::endl;
}
std::cout << "All threads terminated" << std::endl;
return 0;
}