1

由于功能的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");
4

2 回答 2

3

但在我看来,两者都太过分了。

如果您希望它与等待句柄一起工作,那就是您必须做的。但是,如果您所需要的只是在所有线程完成之前会阻塞的东西,您可以使用Semaphore或者可能是Synchronization Barrier

于 2013-09-23T21:55:39.087 回答
1

随着Jim Mischel 的回答,我找到了解决方案。信号量对象可以解决两个问题:

  • 等待所有线程
  • 限制运行线程的数量

这是一个小而独立的示例:

#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;
}
于 2013-09-25T08:44:07.310 回答