64位精度睡眠功能?

问题描述 投票:-2回答:3

目前Sleep只需要一个DWORD(32位)。是否有任何替代方案需要DWORDLONG(64位)?

我正在使用RNG,其中每增加一个字节,总的等待时间就会增加。使用32位整数时,总时间为5分钟,我想增加它。

c winapi timer sleep
3个回答
2
投票

Sleep[Ex]内部调用NtDelayExecution - 没有文档但存在于所有windows nt版本中(从nt 4到win 10) - 由ntdll.dll导出 - 使用来自wdk的ntdll.lib或ntdllp.lib。由于内核中的这个调用将被称为记录函数KeDelayExecutionThread

//extern "C"
NTSYSAPI 
NTSTATUS
NTAPI
NtDelayExecution(
  IN BOOLEAN              Alertable,
  IN PLARGE_INTEGER       Interval );
  • 可报警

如果等待是可警告的,则指定TRUE。较低级别的驱动程序应指定FALSE。

  • 间隔

指定等待发生的绝对或相对时间(以100纳秒为单位)。负值表示相对时间。绝对到期时间跟踪系统时间的任何变化;相对到期时间不受系统时间更改的影响。

Sleep[Ex]是win32 shell,在这个原生api上,限制间隔值(从64位到32位)不能设置绝对时间(可能使用NtDelayExecution)并忽略警报(如果等待警报,我们可以通过警报线程退出NtDelayExecution)

所以你可以通过Sleep[Ex]直接调用这个api

所以Sleep(dwMilliseconds)Sleep(dwMilliseconds, false)

SleepEx(dwMilliseconds, bAlertable) 

呼叫

LARGE_INTEGER  Interval;
Interval.QuadPart = -(dwMilliseconds * 10000);
NtDelayExecution(bALertable, &Interval);

请注意,如果可警告等待,可以通过apc(api return STATUS_USER_APC)或通过警报(STATUS_ALERTED将被返回。我们可以通过NtAlertThread警告线程)来破坏它。 SleepEx检查返回状态,如果STATUS_ALERTED - 再次开始等待更新的间隔。所以SleepEx等不能通过警报(NtAlertThread)打破,但NtDelayExecution可以


1
投票

Sleep()需要几毫秒。最大DWORD值4294967295将导致49.7天的超时时间。对于大多数目的而言,这是一个足够好的最大值,但如果您确定要有64位睡眠参数,则可以将多个Sleep()调用链接在一起。这将把Sleep()的最大毫秒数改为18446744073709551615,这是几十万个世纪的数量级:

VOID WINAPI Sleep64(DWORDLONG dwlMilliseconds)
{
    while (dwlMilliseconds)
    {
        Sleep(min(0xFFFFFFFE, dwlMilliseconds));
        dwlMilliseconds -= min(0xFFFFFFFE, dwlMilliseconds);
    }
}

我测试了这个并且可以验证它是否有效。


0
投票

是否有任何替代方案需要DWORDLONG(64位)?

不。你需要在循环中多次调用Sleep

有趣的测试和调试多个月的睡眠。

© www.soinside.com 2019 - 2024. All rights reserved.