如何克服WaitForMultipleObjects的MAXIMUM_WAIT_OBJECTS限制?

时间:2013-09-23 21:29:49

标签: c++ multithreading winapi synchronization

由于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");

2 个答案:

答案 0 :(得分:3)

  

但在我看来,两者都是太费力了。

如果您希望它与等待句柄一起使用,那就是您必须要做的事情。但是,如果您需要的是在所有线程完成之前阻塞的东西,您可以使用SemaphoreSynchronization 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;
}