WaitForMultipleObjects等待超过MAXIMUM_WAIT_OBJECTS个的内核对象 (同时任意等待某个事件 bwaitAll = FALSE)

多线程编程时用WaitForMultipleObjects函数可以很方便的等待多个线程的退出。但是在一个并行计算pi的程序中出现了一些小问题:为了对比测试不同线程数量的效率,不断加大 线程数,而当线程数大于64时却出现了下图的结果

而且第一行的输出基本上是一运行就输出,而下面的“任意键继续”却等了一会儿才跳出来,显然程序并没有按照设计等到所有线程计算完毕后才继续执行输出pi值。

 

百度了一下,看到http://www.cnblogs.com/ayanmw/archive/2012/11/13/2767628.html的作者也遇到了和我一样的问题,不过他也没有给出解决方案。

只好乖乖的去msdn找这个函数的用法(http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms687025(v=vs.85).aspx),看到了这样一段话:

 

To wait on more than MAXIMUM_WAIT_OBJECTS handles, use one of the following methods:

  • Create a thread to wait on MAXIMUM_WAIT_OBJECTS handles, then wait on that thread plus the other handles. Use this technique to break the handles into groups ofMAXIMUM_WAIT_OBJECTS.
  • Call RegisterWaitForSingleObject to wait on each handle. A wait thread from the thread pool waits onMAXIMUM_WAIT_OBJECTS registered objects and assigns a worker thread after the object is signaled or the time-out interval expires.

看来这个函数确实有个数的限制,最多不能超过MAXIMUM_WAIT_OBJECTS个。这个宏的定义在WinNT.h中

#define MAXIMUM_WAIT_OBJECTS 64     // Maximum number of wait objects

 

而如果要想等待超过它的数量,按msdn所说有两种方法,都是先要将原来的Objects分成N组,每组不超过MAXIMUM_WAIT_OBJECTS个。方法1是新建N个线程分别等待N组对象,主线程等待这N个线程(若N还是大于MAXIMUM_WAIT_OBJECTS则还可以再次使用这个方法,形成一个树形结构);而方法2是先等待第1组,若第1组超时或收到了信号则继续等待第2组,依次类推顺序等待每一组。

 

由于第二种方法相对实现比较简单,我选择了这种方法

//************************************
// @Method:   SyncWaitForMultipleObjs
// Access:    public 
// Returns:   Same as WaitForMultipleObjects.
// Parameter: handles : An array of object handles to wait.
// Parameter: count : The count of handles.
// brief:     Synchronize waiting for all objects signaled.synchronize
//************************************
DWORD ITS_Router::SyncWaitForMultipleObjs(HANDLE * handles, size_t count)
{  
    int waitNumbers = count / MAXIMUM_WAIT_OBJECTS + 1;

    DWORD dRes = 0;
    DWORD nCount = 0;
    for (int i = 0; i < waitNumbers; ++i)
    {
        nCount = (i == waitNumbers-1)?(count - i*MAXIMUM_WAIT_OBJECTS):MAXIMUM_WAIT_OBJECTS;

        dRes = WaitForMultipleObjects(nCount, handles+i*MAXIMUM_WAIT_OBJECTS, FALSE, 100);
        if (dRes == WAIT_TIMEOUT || dRes == WAIT_FAILED)
        {
            if (nCount < MAXIMUM_WAIT_OBJECTS)
            {
                return dRes;
            }
            continue;
        }
        else
        {
            return dRes+i*MAXIMUM_WAIT_OBJECTS;
        }
    }

    return dRes; 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值