WaitForSingleObjectEx超时参数说明

WaitForSingleObjectEx函数原型如下

DWORD WINAPI WaitForSingleObjectEx(
  __in  HANDLE hHandle,
  __in  DWORD dwMilliseconds,
  __in  BOOL bAlertable
);


在SDK6.1文档中,对参数dwMilliseconds说明如下:

The time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled and no completion routines or APCs are queued.If dwMilliseconds is zero, the function tests the object's state and checks for queued completion routines or APCs and then returns immediately. IfdwMilliseconds is INFINITE, the function's time-out interval never elapses.

我对其中标红语句的理解是,如何超过时间间隔,即使(even if)对象信号未被触发并且没有完成例程或者APC例程排队。我觉得比较难翻译及理解。于是我又查了下网上MSDN,对参数dwMilliseconds说明如下:

The time-out interval, in milliseconds. If a nonzero value is specified, the function waits until the object is signaled, an I/O completion routine or APC is queued, or the interval elapses. IfdwMilliseconds is zero, the function does not enter a wait state if the criteria is not met; it always returns immediately. IfdwMilliseconds is INFINITE, the function will return only when the object is signaled or an I/O completion routine or APC is queued.

还是没有搞清楚若超过时间间隔,但是当前有完成例程或者APC例程,函数是否返回,于是写了个小Demo测试了一下

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;

VOID NTAPI ApcFun(__in ULONG_PTR Parameter)
{
	cout<<"ApcFun Running."<<endl;
	Sleep(10000);
}

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hEvent=CreateEvent(NULL,FALSE,FALSE,_T(""));

	DWORD dwRet=QueueUserAPC(ApcFun,GetCurrentThread(),NULL);
	cout<<dwRet<<endl;
	dwRet=QueueUserAPC(ApcFun,GetCurrentThread(),NULL);
	cout<<dwRet<<endl;
	dwRet=WaitForSingleObjectEx(hEvent,1000,TRUE);
	cout<<dwRet<<endl;

	CloseHandle(hEvent);
	return 0;
}


测试结果是即使超时时间已到,若当前存在完成例程或者APC例程,会把所有的例程执行完毕后才会返回。

如果WaitForSingleObjectEx第3个参数为TRUE,那么WaitForSingleObjectEx在执行时发现存在APC例程需要执行,则当前等待线程执行APC过程,执行完毕后,

不管同步对象是否有信号或者是否超时,函数返回,返回值为WAIT_IO_COMPLETION。

            我写个小demo供测试

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
using namespace std;

HANDLE hEvent;

DWORD WINAPI ThreadFun(LPVOID lpThreadParameter)
{
	hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
	DWORD dwRet=WaitForSingleObjectEx(hEvent,INFINITE,TRUE);
	CloseHandle(hEvent);
	return 0;
}

VOID NTAPI UserApc(ULONG_PTR Parameter)
{
	for (int i=0;i<10000;i++)
	{
		for (int j=0;j<10000;j++)
		{
		}
		cout<<i<<endl;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hThread=CreateThread(NULL,NULL,ThreadFun,NULL,NULL,NULL);
	Sleep(500);
	DWORD dwRet=QueueUserAPC(UserApc,hThread,NULL);
	SetEvent(hEvent);
	WaitForSingleObject(hThread,INFINITE);
	return 0;
}


 

在主函数中Sleep(500)的意思是使子线程初始化完毕并且线程函数ThreadFun能够运行起来,若没有这一句,有很大的可能

QueueUserAPC执行完毕后子线程还在初始化中,此时若发现APC队列中存在APC例程,则会先执行apc队列,然后再执行

线程函数,这样会造成WaitForSingleObjectEx执行是apc队列是空的,达不到测试的目的,

就算APC执行过程中同步对象已然有信号,WaitForSingleObjectEx已然会返回WAIT_IO_COMPLETION

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值