WaitForMultipleObjects等待多对象用法说明

引言

在window c++编程中,为了等待线程结束或者同步对象有限号,我们常常使用WaitForSingleObjectAPI函数,从字面上就可以看出,该接口是用于等待单个对象。而实际编码中,我们会遇到需要等待多个对象同时符合条件或者多个对象中的一个符合条件就执行某个事件,而本文讨论的WaitForMultipleObjectsAPI就可以满足同时监控多个对象的需求。为了对比它们的差异点,下面分别给出接口参数。

WaitForSingleObject 接口:

DWORD WaitForSingleObject(
  HANDLE hHandle,      /*等待对象的句柄*/
  DWORD dwMilliseconds /*等待事件*/
);

WaitForMultipleObjects 接口:

DWORD WaitForMultipleObjects(
  DWORD        nCount,        /*监控对象的个数*/
  const HANDLE *lpHandles,    /*一组对象句柄的指针*/
  BOOL         bWaitAll,      /*是否等待全部符合条件*/
  DWORD        dwMilliseconds /*等待事件*/
);
异同点说明

从上面就可以看出,这个两个的接口参数不同点,这里主要说明下他们的返回值和监控的对象异同点。

返回值差异点:

WaitForSingleObject 返回值:

  • WAIT_OBJECT_0 监控对象有信号
  • WAIT_TIMEOUT 规定时间内未返回或者有信号
  • WAIT_FAILED 等待是失败,具体情况见查看msdn

WaitForMultipleObjects 返回值:

WaitForMultipleObjects 返回值比WaitForSingleObject 多一个WAIT_ABANDONED_0,这个不在此次讨论范围内。

当bWaitAll为TRUE时,它们的返回值是是一样的分别是WAIT_OBJECT_0, WAIT_TIMEOUT,WAIT_FAILED.

当bWaitAll为FALSE时,并且没有失败或者超时情况下,它可以监控到是哪一个对象有信号或者线程返回。其返回值访问从WAIT_OBJECT_0WAIT_OBJECT_0 + nCount - 1

当只有一个对象返回时,其返回值 - WAIT_OBJECT_0就是句柄数组的索引。

WAIT_OBJECT_0 + 0  代表句柄数组中的第0个对象
WAIT_OBJECT_0 + 1  代表句柄数组中的第1个对象
...
WAIT_OBJECT_0 + nCount -1  代表句柄数组中的最后一个对象

当规定时间内,有多个对象有信号或者线程返回,其返回值的其中最小的一个

监控对象

都会监控的对象列表:

  • Event
  • Mutex
  • Process
  • Semaphore
  • Thread

WaitForMultipleObjects 新增的监控列表:

  • Change notification
  • Console input
  • Memory resource notification
  • Waitable timer
示例代码

以下代码可以直接在vs编译器中执行,大家可以更加不同的参数进行测试和验证。

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <process.h>    

unsigned  __stdcall SetMyEvent(void *lpParam)
{
    if (NULL != lpParam)
    {
        HANDLE* hEvent = (HANDLE*)lpParam;
        Sleep(2000);
        ::SetEvent(*hEvent);
    }

    return 0;
}

unsigned  __stdcall SleepThread(void *pSleeptime)
{
    if (NULL != pSleeptime)
    {
        int Sleeptime  = (*(int*)pSleeptime) ;
        Sleep(Sleeptime * 1000);
    }

    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    const int EVENT_NUM = 2;

    HANDLE hObject[EVENT_NUM] = {NULL,NULL};

    //创建线程,2秒后hObject[0]事件对象变成有信号
    hObject[0] = ::CreateEvent(NULL,FALSE,FALSE,NULL);
    HANDLE hThread = (HANDLE)_beginthreadex(NULL,0,SetMyEvent,(void*)&hObject[0],0,NULL);
    CloseHandle(hThread); //后续不会对该线程进行操作,直接关掉句柄


    //创建线程,并等待线程结束
    int nSleepTime = 1;
    hObject[1] = (HANDLE) _beginthreadex(NULL,0,SleepThread,(void*)&nSleepTime,0,NULL);

    //等待事件对象有信号、线程返回
    DWORD dwEvent = WaitForMultipleObjects(EVENT_NUM, hObject, FALSE/*TRUE*/, 1500);
    switch(dwEvent)
    {
    case WAIT_OBJECT_0 + 0: /*hObject[0]有信号*/
        {
           printf("event arrived ...\n");
           /*TODO 自定义特殊处理*/
           break;
        }
    case WAIT_OBJECT_0 + 1: /*hObject[1]线程返回*/
        {
            printf("thread return ...\n");
            /*TODO 自定义特殊处理*/
            break;
        }
    case WAIT_TIMEOUT: /*规定时间内,定义的事件和线程均未返回或者有信号*/
        {
            printf("wait multi object timeout ...\n");
            /*TODO 自定义特殊处理*/
            break;
        }
    default:
        {
            printf("wait for multi object error...\n");
        }
    }

    for (int i = 0; i < EVENT_NUM; i++)
    {
        CloseHandle(hObject[i]);
    }

    return 0;
}

更多资料可参见MSDN

https://docs.microsoft.com/zh-cn/windows/win32/sync/waiting-for-multiple-objects

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值