Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows7:超调C++;std::此线程::睡眠 我们的代码是用C++ 11编写的(VS201/Win 764位)。C++库为我们使用的函数提供了睡眠。我们观察到的C++ +>代码>睡眠有时表现出较大的过冲。换句话说,我们要求睡眠15毫秒,但睡眠时间为100毫秒。当系统负载较高时,我们会看到这种情况_C++_Windows_Winapi_Sleep - Fatal编程技术网

Windows7:超调C++;std::此线程::睡眠 我们的代码是用C++ 11编写的(VS201/Win 764位)。C++库为我们使用的函数提供了睡眠。我们观察到的C++ +>代码>睡眠有时表现出较大的过冲。换句话说,我们要求睡眠15毫秒,但睡眠时间为100毫秒。当系统负载较高时,我们会看到这种情况

Windows7:超调C++;std::此线程::睡眠 我们的代码是用C++ 11编写的(VS201/Win 764位)。C++库为我们使用的函数提供了睡眠。我们观察到的C++ +>代码>睡眠有时表现出较大的过冲。换句话说,我们要求睡眠15毫秒,但睡眠时间为100毫秒。当系统负载较高时,我们会看到这种情况,c++,windows,winapi,sleep,C++,Windows,Winapi,Sleep,我的第一个反应是:“当然,如果系统上有很多负载,而其他线程正在使用CPU,那么睡眠时间会更长”。 然而,“有趣的”是,如果我们用Windows API“sleep”调用替换的sleep\u,那么我们就看不到这种行为。我还看到水下sleep\u for函数调用windowapisleep方法 各国的文件: 函数至少在Rel_time指定的时间内阻止调用线程。此函数不会引发任何异常 因此,从技术上讲,该功能正在发挥作用。但是,我们并没有看到C++ 睡眠>对于和常规睡眠(EX)< /C>函数。 有人能

我的第一个反应是:“当然,如果系统上有很多负载,而其他线程正在使用CPU,那么睡眠时间会更长”。 然而,“有趣的”是,如果我们用Windows API“sleep”调用替换的
sleep\u,那么我们就看不到这种行为。我还看到水下
sleep\u for
函数调用windowapi
sleep
方法

各国的文件:

函数至少在Rel_time指定的时间内阻止调用线程。此函数不会引发任何异常

因此,从技术上讲,该功能正在发挥作用。但是,我们并没有看到C++ <代码>睡眠>对于和常规<代码>睡眠(EX)< /C>函数。
有人能解释一下这种行为吗?

如果对vs SleepEx使用sleep_,会执行很多额外的代码

例如,调用SleepEx(15)在调试模式下生成以下程序集(Visual Studio 2015):

相比之下,这个代码

const std::chrono::milliseconds duration(15);
std::this_thread::sleep_for(duration);
生成以下内容:

; 9    :    std::this_thread::sleep_for(std::chrono::milliseconds(15));

    mov DWORD PTR $T1[ebp], 15          ; 0000000fH
    lea eax, DWORD PTR $T1[ebp]
    push    eax
    lea ecx, DWORD PTR $T2[ebp]
    call    duration
    push    eax
    call    sleep_for
    add esp, 4
这需要:

duration PROC ; std::chrono::duration<__int64,std::ratio<1,1000> >::duration<__int64,std::ratio<1,1000> ><int,void>, COMDAT
; _this$ = ecx

; 113  :        {   // construct from representation

    push    ebp
    mov ebp, esp
    sub esp, 204                ; 000000ccH
    push    ebx
    push    esi
    push    edi
    push    ecx
    lea edi, DWORD PTR [ebp-204]
    mov ecx, 51                 ; 00000033H
    mov eax, -858993460             ; ccccccccH
    rep stosd
    pop ecx
    mov DWORD PTR _this$[ebp], ecx

; 112  :            : _MyRep(static_cast<_Rep>(_Val))

    mov eax, DWORD PTR __Val$[ebp]
    mov eax, DWORD PTR [eax]
    cdq
    mov ecx, DWORD PTR _this$[ebp]
    mov DWORD PTR [ecx], eax
    mov DWORD PTR [ecx+4], edx

; 114  :        }

    mov eax, DWORD PTR _this$[ebp]
    pop edi
    pop esi
    pop ebx
    mov esp, ebp
    pop ebp
    ret 4
duration ENDP
您还应注意,根据MSDN文档,即使SleepEx也可能无法给出100%的准确结果


此函数使线程放弃剩余的时间片,并在基于DWM毫秒值的间隔内变得不可命名。系统时钟以恒定速率“滴答”作响。如果dwms小于系统时钟的分辨率,则线程的睡眠时间可能小于指定的时间长度。如果DWM大于一个刻度但小于两个,则等待时间可以在一到两个刻度之间,依此类推。要提高睡眠间隔的准确性,请调用timeGetDevCaps函数确定支持的最小计时器分辨率,并调用timeBeginPeriod函数将计时器分辨率设置为其最小值。调用timeBeginPeriod时请小心,因为频繁的调用会显著影响系统时钟、系统电源使用和计划程序。如果调用timeBeginPeriod,请在应用程序的早期调用它一次,并确保在应用程序的最后调用timeEndPeriod函数。

在绝大多数操作系统(包括Windows、Linux和BSD)上,对于过度睡眠和睡眠不足,睡眠通常都不可靠。半个C++ C++线程库的坏措辞(真的,花费了这么长时间,线程已经被研究了几十年了,你不能想出更好的东西)。需要——看到发布的引用——一个兼容的实现首先睡觉,然后调用一个时间函数来检查确实请求的最小值已经通过了,可能还会再睡觉。这真是太没用了,太愚蠢了……一句话,
sleep\u和
sleep
(Win32)根本不是一回事。@Damon,你所描述的是
睡眠直到
所需要的,而不是
睡眠的
sleep\u,并且只对可以调整的非单调时钟是必需的。为
实现
sleep\u不需要调用时间函数。例如,如果它是使用
nanosleep
实现的,那么该函数将告诉您它是否在请求的时间内睡眠(或者被信号中断并提前返回)。@Damon:我刚刚检查了Visual Studio 2015的
sleep\u的实现。它只计算过期时间,并将调用转发到
sleep\u,直到
sleep\u直到
然后调用
sleep
,这可能是一个循环,以防止提前到期。总之,
sleep\u for
sleep
几乎是一样的,只是
sleep\u for
不会提前过期。@IInspectable:不,正如您所说,
sleep\u until
运行循环,而
sleep\u for
调用前者。这正是我要说的。睡眠两次可能会导致这种“花很长时间”的现象。每次睡眠时,请求的时间都会四舍五入到调度程序粒度(在Vista之前和Vista之后的窗口中也是不同的),并且线程在该时间结束之前(通常)不会准备就绪。可通过以下事实进行验证:
for(int i=0;i<1000;++i)Sleep(1)
睡眠(1000)
需要更长的时间。事实上,你是否早点回来根本不重要。。。
duration PROC ; std::chrono::duration<__int64,std::ratio<1,1000> >::duration<__int64,std::ratio<1,1000> ><int,void>, COMDAT
; _this$ = ecx

; 113  :        {   // construct from representation

    push    ebp
    mov ebp, esp
    sub esp, 204                ; 000000ccH
    push    ebx
    push    esi
    push    edi
    push    ecx
    lea edi, DWORD PTR [ebp-204]
    mov ecx, 51                 ; 00000033H
    mov eax, -858993460             ; ccccccccH
    rep stosd
    pop ecx
    mov DWORD PTR _this$[ebp], ecx

; 112  :            : _MyRep(static_cast<_Rep>(_Val))

    mov eax, DWORD PTR __Val$[ebp]
    mov eax, DWORD PTR [eax]
    cdq
    mov ecx, DWORD PTR _this$[ebp]
    mov DWORD PTR [ecx], eax
    mov DWORD PTR [ecx+4], edx

; 114  :        }

    mov eax, DWORD PTR _this$[ebp]
    pop edi
    pop esi
    pop ebx
    mov esp, ebp
    pop ebp
    ret 4
duration ENDP
    sleep_for PROC ; std::this_thread::sleep_for<__int64,std::ratio<1,1000> >, COMDAT

    ; 151  :    {   // sleep for duration

        push    ebp
        mov ebp, esp
        sub esp, 268                ; 0000010cH
        push    ebx
        push    esi
        push    edi
        lea edi, DWORD PTR [ebp-268]
        mov ecx, 67                 ; 00000043H
        mov eax, -858993460             ; ccccccccH
        rep stosd
        mov eax, DWORD PTR ___security_cookie
        xor eax, ebp
        mov DWORD PTR __$ArrayPad$[ebp], eax

    ; 152  :    stdext::threads::xtime _Tgt = _To_xtime(_Rel_time);

        mov eax, DWORD PTR __Rel_time$[ebp]
        push    eax
        lea ecx, DWORD PTR $T1[ebp]
        push    ecx
        call    to_xtime
        add esp, 8
        mov edx, DWORD PTR [eax]
        mov DWORD PTR $T2[ebp], edx
        mov ecx, DWORD PTR [eax+4]
        mov DWORD PTR $T2[ebp+4], ecx
        mov edx, DWORD PTR [eax+8]
        mov DWORD PTR $T2[ebp+8], edx
        mov eax, DWORD PTR [eax+12]
        mov DWORD PTR $T2[ebp+12], eax
        mov ecx, DWORD PTR $T2[ebp]
        mov DWORD PTR __Tgt$[ebp], ecx
        mov edx, DWORD PTR $T2[ebp+4]
        mov DWORD PTR __Tgt$[ebp+4], edx
        mov eax, DWORD PTR $T2[ebp+8]
        mov DWORD PTR __Tgt$[ebp+8], eax
        mov ecx, DWORD PTR $T2[ebp+12]
        mov DWORD PTR __Tgt$[ebp+12], ecx

    ; 153  :    sleep_until(&_Tgt);

        lea eax, DWORD PTR __Tgt$[ebp]
        push    eax
        call    sleep_until
        add esp, 4

    ; 154  :    }

        push    edx
        mov ecx, ebp
        push    eax
        lea edx, DWORD PTR $LN5@sleep_for
        call    @_RTC_CheckStackVars@8
        pop eax
        pop edx
        pop edi
        pop esi
        pop ebx
        mov ecx, DWORD PTR __$ArrayPad$[ebp]
        xor ecx, ebp
        call    @__security_check_cookie@4
        add esp, 268                ; 0000010cH
        cmp ebp, esp
        call    __RTC_CheckEsp
        mov esp, ebp
        pop ebp
        ret 0
        npad    3
    $LN5@sleep_for:
        DD  1
        DD  $LN4@sleep_for
    $LN4@sleep_for:
        DD  -24                 ; ffffffe8H
        DD  16                  ; 00000010H
        DD  $LN3@sleep_for
    $LN3@sleep_for:
        DB  95                  ; 0000005fH
        DB  84                  ; 00000054H
        DB  103                 ; 00000067H
        DB  116                 ; 00000074H
        DB  0
    sleep_for ENDP
to_xtime PROC ; std::_To_xtime<__int64,std::ratio<1,1000> >, COMDAT

; 758  :    {   // convert duration to xtime

    push    ebp
    mov ebp, esp
    sub esp, 348                ; 0000015cH
    push    ebx
    push    esi
    push    edi
    lea edi, DWORD PTR [ebp-348]
    mov ecx, 87                 ; 00000057H
    mov eax, -858993460             ; ccccccccH
    rep stosd
    mov eax, DWORD PTR ___security_cookie
    xor eax, ebp
    mov DWORD PTR __$ArrayPad$[ebp], eax

; 759  :    xtime _Xt;
; 760  :    if (_Rel_time <= chrono::duration<_Rep, _Period>::zero())

    lea eax, DWORD PTR $T7[ebp]
    push    eax
    call    duration_zero ; std::chrono::duration<__int64,std::ratio<1,1000> >::zero
    add esp, 4
    push    eax
    mov ecx, DWORD PTR __Rel_time$[ebp]
    push    ecx
    call    chronos_operator ; std::chrono::operator<=<__int64,std::ratio<1,1000>,__int64,std::ratio<1,1000> >
    add esp, 8
    movzx   edx, al
    test    edx, edx
    je  SHORT $LN2@To_xtime

; 761  :        {   // negative or zero relative time, return zero
; 762  :        _Xt.sec = 0;

    xorps   xmm0, xmm0
    movlpd  QWORD PTR __Xt$[ebp], xmm0

; 763  :        _Xt.nsec = 0;

    mov DWORD PTR __Xt$[ebp+8], 0

; 764  :        }
; 765  :    else

    jmp $LN3@To_xtime
$LN2@To_xtime:

; 766  :        {   // positive relative time, convert
; 767  :        chrono::nanoseconds _T0 =
; 768  :            chrono::system_clock::now().time_since_epoch();

    lea eax, DWORD PTR $T5[ebp]
    push    eax
    lea ecx, DWORD PTR $T6[ebp]
    push    ecx
    call    system_clock_now ; std::chrono::system_clock::now
    add esp, 4
    mov ecx, eax
    call    time_since_ephoch ; std::chrono::time_point<std::chrono::system_clock,std::chrono::duration<__int64,std::ratio<1,10000000> > >::time_since_epoch
    push    eax
    lea ecx, DWORD PTR __T0$8[ebp]
    call    duration ; std::chrono::duration<__int64,std::ratio<1,1000000000> >::duration<__int64,std::ratio<1,1000000000> ><__int64,std::ratio<1,10000000>,void>

; 769  :        _T0 += _Rel_time;

    mov eax, DWORD PTR __Rel_time$[ebp]
    push    eax
    lea ecx, DWORD PTR $T4[ebp]
    call    duration_ratio ; std::chrono::duration<__int64,std::ratio<1,1000000000> >::duration<__int64,std::ratio<1,1000000000> ><__int64,std::ratio<1,1000>,void>
    lea ecx, DWORD PTR $T4[ebp]
    push    ecx
    lea ecx, DWORD PTR __T0$8[ebp]
    call    duration_ratio ; std::chrono::duration<__int64,std::ratio<1,1000000000> >::operator+=

; 770  :        _Xt.sec = chrono::duration_cast<chrono::seconds>(_T0).count();

    lea eax, DWORD PTR __T0$8[ebp]
    push    eax
    lea ecx, DWORD PTR $T3[ebp]
    push    ecx
    call    duration_cast ; std::chrono::duration_cast<std::chrono::duration<__int64,std::ratio<1,1> >,__int64,std::ratio<1,1000000000> >
    add esp, 8
    mov ecx, eax
    call    duration_count ; std::chrono::duration<__int64,std::ratio<1,1> >::count
    mov DWORD PTR __Xt$[ebp], eax
    mov DWORD PTR __Xt$[ebp+4], edx

; 771  :        _T0 -= chrono::seconds(_Xt.sec);

    lea eax, DWORD PTR __Xt$[ebp]
    push    eax
    lea ecx, DWORD PTR $T1[ebp]
    call    duration_ratio ; std::chrono::duration<__int64,std::ratio<1,1> >::duration<__int64,std::ratio<1,1> ><__int64,void>
    push    eax
    lea ecx, DWORD PTR $T2[ebp]
    call    duration_ratio ; std::chrono::duration<__int64,std::ratio<1,1000000000> >::duration<__int64,std::ratio<1,1000000000> ><__int64,std::ratio<1,1>,void>
    lea ecx, DWORD PTR $T2[ebp]
    push    ecx
    lea ecx, DWORD PTR __T0$8[ebp]
    call    duration_ratio ; std::chrono::duration<__int64,std::ratio<1,1000000000> >::operator-=

; 772  :        _Xt.nsec = (long)_T0.count();

    lea ecx, DWORD PTR __T0$8[ebp]
    call    duration_ratio ; std::chrono::duration<__int64,std::ratio<1,1000000000> >::count
    mov DWORD PTR __Xt$[ebp+8], eax
$LN3@To_xtime:

; 773  :        }
; 774  :    return (_Xt);

    mov eax, DWORD PTR $T9[ebp]
    mov ecx, DWORD PTR __Xt$[ebp]
    mov DWORD PTR [eax], ecx
    mov edx, DWORD PTR __Xt$[ebp+4]
    mov DWORD PTR [eax+4], edx
    mov ecx, DWORD PTR __Xt$[ebp+8]
    mov DWORD PTR [eax+8], ecx
    mov edx, DWORD PTR __Xt$[ebp+12]
    mov DWORD PTR [eax+12], edx
    mov eax, DWORD PTR $T9[ebp]

; 775  :    }

    push    edx
    mov ecx, ebp
    push    eax
    lea edx, DWORD PTR $LN8@To_xtime
    call    @_RTC_CheckStackVars@8
    pop eax
    pop edx
    pop edi
    pop esi
    pop ebx
    mov ecx, DWORD PTR __$ArrayPad$[ebp]
    xor ecx, ebp
    call    @__security_check_cookie@4
    add esp, 348                ; 0000015cH
    cmp ebp, esp
    call    __RTC_CheckEsp
    mov esp, ebp
    pop ebp
    ret 0
$LN8@To_xtime:
    DD  2
    DD  $LN7@To_xtime
$LN7@To_xtime:
    DD  -24                 ; ffffffe8H
    DD  16                  ; 00000010H
    DD  $LN5@To_xtime
    DD  -40                 ; ffffffd8H
    DD  8
    DD  $LN6@To_xtime
$LN6@To_xtime:
    DB  95                  ; 0000005fH
    DB  84                  ; 00000054H
    DB  48                  ; 00000030H
    DB  0
$LN5@To_xtime:
    DB  95                  ; 0000005fH
    DB  88                  ; 00000058H
    DB  116                 ; 00000074H
    DB  0
to_xtime ENDP 
sleep_until PROC    ; std::this_thread::sleep_until, COMDAT

; 131  :    {   // sleep until _Abs_time

    push    ebp
    mov ebp, esp
    sub esp, 192                ; 000000c0H
    push    ebx
    push    esi
    push    edi
    lea edi, DWORD PTR [ebp-192]
    mov ecx, 48                 ; 00000030H
    mov eax, -858993460             ; ccccccccH
    rep stosd

; 132  :    _Thrd_sleep(_Abs_time);

    mov esi, esp
    mov eax, DWORD PTR __Abs_time$[ebp]
    push    eax
    call    DWORD PTR __imp___Thrd_sleep
    add esp, 4
    cmp esi, esp
    call    __RTC_CheckEsp

; 133  :    }

    pop edi
    pop esi
    pop ebx
    add esp, 192                ; 000000c0H
    cmp ebp, esp
    call    __RTC_CheckEsp
    mov esp, ebp
    pop ebp
    ret 0
sleep_until ENDP