本质上还是有时间概念的,只是被MS给藏起来了。说到底就是个do while(true)循环.满足条件了就goto跳出。
WaitForSingleObject是kernel32.dll的导出函数,dasm下看到WaitForSingleObject又调用了ntdll.dll的NtWaitForSingleObject.
NtWaitForSingleObject又调用了KeWaitForSingleObject
以下是KeWaitForSingleObject的部分实现代码。(以上部分为原创,代码部分为转贴。)
do
{
WaitStatus = CurrentThread->WaitStatus;
CurrentThread->WaitBlockList = WaitBlock = &CurrentThread->WaitBlock;
CurrentObject = (PDISPATCHER_HEADER)Object;
if (KiIsObjectSignaled(CurrentObject, CurrentThread))
{
if (CurrentObject->SignalState != MINLONG)
{
KiSatisfyObjectWait(CurrentObject, CurrentThread);
Status = STATUS_WAIT_0;
goto WaitDone;
}
else
{
if (CurrentObject->Type == MutantObject)
{
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
}
}
}
WaitBlock->Object = CurrentObject;
WaitBlock->Thread = CurrentThread;
WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0);
WaitBlock->WaitType = WaitAny;
WaitBlock->NextWaitBlock = NULL;
KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status);
CurrentThread->WaitStatus = Status;
if (Timeout != NULL)
{
//略.有超时设置的情况
}
InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);
if (CurrentThread->Queue)
{
DPRINT("Waking Queue\n");
KiWakeQueue(CurrentThread->Queue);
}
PsBlockThread(&Status, Alertable, WaitMode, (UCHAR)WaitReason);
if (Status != STATUS_KERNEL_APC)
{
return Status;
}
DPRINT("Looping Again\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
} while (TRUE);
WaitDone:
综合这些考虑。是有时间概念的。而这个do while究竟占用多少CPU资源就不好算了,但是肯定是一个有时间概念的东西。
下记是它的是使用方法。【mIdNum是要监视的进程ID】
pHandle = OpenProcess(SYNCHRONIZE, False, mIdNum)
ret = WaitForSingleObject(pHandle, INFINITE)
ret = CloseHandle(pHandle)
可以看出,WaitForSingleObject是以同步的方式执行的,所以没有时间的概念。
当捕获的pHandle结束了,等待也即终止。