您的位置首页百科知识

WaitForSingleObject()多久判断一次是否有信号

WaitForSingleObject()多久判断一次是否有信号

本质上还是有时间概念的,只是被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结束了,等待也即终止。

抖音看短剧