在多线程环境中使用Sleep函数会有什么问题?

tony2278 2013-09-18 03:13:37
eg:

Sleep(1000); //会对主程序有影响吗?
...全文
2965 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
Vegertar 2013-09-24
  • 打赏
  • 举报
回复
引用 15 楼 healer_kx 的回复:
[quote=引用 3 楼 zhao4zhong1 的回复:] 参考Sleep源代码(如果有的话)
你有吗?[/quote] 老赵又被将了。他要是有win32的源码,呃。。
healer_kx 2013-09-24
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
参考Sleep源代码(如果有的话)
你有吗?
tony2278 2013-09-24
  • 打赏
  • 举报
回复
正如12楼所说的,“Windows Sleep 不是必须的!"
tony2278 2013-09-24
  • 打赏
  • 举报
回复
已解决。 解决办法:在该线程中读取系统时间,当发现时间间隔大于X秒的时候,就去做某件事,如发指令使纸币器继续持币。 因为纸币器持币的时间固定为10秒。当在这10秒内不发送持币指令,纸币器就会退币。 原先该线程内有Sleep(5000),但当长时间运行时,该线程未必有机会很快得到时间片继续运行,加上它自身Sleep了5秒,所以会出现10秒内纸币器也没有收到继续持币的指令。 结论:在多线程的环境中,使用Sleep函数还是有所顾虑的。
赵4老师 2013-09-24
  • 打赏
  • 举报
回复
引用 23 楼 Vegertar 的回复:
哥总算是见识了! 就凭老赵这劲头,能刷出5个星,实属当然。 但行好事,莫问前程。 慢走不送。
Sorry!我刚才失态了。
Vegertar 2013-09-24
  • 打赏
  • 举报
回复
哥总算是见识了! 就凭老赵这劲头,能刷出5个星,实属当然。 但行好事,莫问前程。 慢走不送。
大道曙光 2013-09-24
  • 打赏
  • 举报
回复
线程优先级也要处理好。
赵4老师 2013-09-24
  • 打赏
  • 举报
回复
引用 20 楼 Vegertar 的回复:
DLL反编译出来的东西就不要拿出来了,OK?当哥是小白呀! Knuth这等提倡用汇编来写代码的科学家,就算是微软,呵呵呵。。。
跟本ID斗!?你不觉得还嫩了点儿吗? C:\windows_2000_source_code\win2k\private\windows\base\client\synch.c

  1570: VOID
  1571: Sleep(
  1572:     DWORD dwMilliseconds
  1573:     )
  1574: 
  1575: /*++
  1576: 
  1577: Routine Description:
  1578: 
  1579:     The execution of the current thread can be delayed for a specified
  1580:     interval of time with the Sleep function.
  1581: 
  1582:     The Sleep function causes the current thread to enter a
  1583:     waiting state until the specified interval of time has passed.
  1584: 
  1585: Arguments:
  1586: 
  1587:     dwMilliseconds - A time-out value that specifies the relative time,
  1588:         in milliseconds, over which the wait is to be completed.  A
  1589:         timeout value of 0 specified that the wait is to timeout
  1590:         immediately.  This allows an application to test an object to
  1591:         determine if it is in the signaled state.  A timeout value of -1
  1592:         specifies an infinite timeout period.
  1593: 
  1594: Return Value:
  1595: 
  1596:     None.
  1597: 
  1598: --*/
  1599: 
  1600: {
  1601:     SleepEx(dwMilliseconds,FALSE);
  1602: }
  1603: 
  1604: DWORD
  1605: APIENTRY
  1606: SleepEx(
  1607:     DWORD dwMilliseconds,
  1608:     BOOL bAlertable
  1609:     )
  1610: 
  1611: /*++
  1612: 
  1613: Routine Description:
  1614: 
  1615:     The execution of the current thread can be delayed for a specified
  1616:     interval of time with the SleepEx function.
  1617: 
  1618:     The SleepEx function causes the current thread to enter a waiting
  1619:     state until the specified interval of time has passed.
  1620: 
  1621:     If the bAlertable parameter is FALSE, the only way the SleepEx
  1622:     returns is when the specified time interval has passed.  If the
  1623:     bAlertable parameter is TRUE, then the SleepEx can return due to the
  1624:     expiration of the time interval (return value of 0), or because an
  1625:     I/O completion callback terminated the SleepEx early (return value
  1626:     of WAIT_IO_COMPLETION).
  1627: 
  1628: Arguments:
  1629: 
  1630:     dwMilliseconds - A time-out value that specifies the relative time,
  1631:         in milliseconds, over which the wait is to be completed.  A
  1632:         timeout value of 0 specified that the wait is to timeout
  1633:         immediately.  A timeout value of -1 specifies an infinite
  1634:         timeout period.
  1635: 
  1636:     bAlertable - Supplies a flag that controls whether or not the
  1637:         SleepEx may terminate early due to an I/O completion callback.
  1638:         A value of TRUE allows this API to complete early due to an I/O
  1639:         completion callback.  A value of FALSE will not allow I/O
  1640:         completion callbacks to terminate this call early.
  1641: 
  1642: Return Value:
  1643: 
  1644:     0 - The SleepEx terminated due to expiration of the time interval.
  1645: 
  1646:     WAIT_IO_COMPLETION - The SleepEx terminated due to one or more I/O
  1647:         completion callbacks.
  1648: 
  1649: --*/
  1650: {
  1651:     LARGE_INTEGER TimeOut;
  1652:     PLARGE_INTEGER pTimeOut;
  1653:     NTSTATUS Status;
  1654: 
  1655:     pTimeOut = BaseFormatTimeOut(&TimeOut,dwMilliseconds);
  1656:     if (pTimeOut == NULL) {
  1657:         //
  1658:         // If Sleep( -1 ) then delay for the longest possible integer
  1659:         // relative to now.
  1660:         //
  1661: 
  1662:         TimeOut.LowPart = 0x0;
  1663:         TimeOut.HighPart = 0x80000000;
  1664:         pTimeOut = &TimeOut;
  1665:         }
  1666: 
  1667: rewait:
  1668:     Status = NtDelayExecution(
  1669:                 (BOOLEAN)bAlertable,
  1670:                 pTimeOut
  1671:                 );
  1672:     if ( bAlertable && Status == STATUS_ALERTED ) {
  1673:         goto rewait;
  1674:         }
  1675:     return Status == STATUS_USER_APC ? WAIT_IO_COMPLETION : 0;
  1676: }
Vegertar 2013-09-24
  • 打赏
  • 举报
回复
DLL反编译出来的东西就不要拿出来了,OK?当哥是小白呀! Knuth这等提倡用汇编来写代码的科学家,就算是微软,呵呵呵。。。
赵4老师 2013-09-24
  • 打赏
  • 举报
回复
引用 16 楼 Vegertar 的回复:
[quote=引用 15 楼 healer_kx 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] 参考Sleep源代码(如果有的话)
你有吗?[/quote] 老赵又被将了。他要是有win32的源码,呃。。[/quote]
    ; *** Sleep (857) ***
	; SYM:Sleep#24EE
0x7c8024ee 8bff           mov     edi,edi
0x7c8024f0 55             push    ebp
0x7c8024f1 8bec           mov     ebp,esp
0x7c8024f3 6a00           push    0x0
0x7c8024f5 ff7508         push    dword ptr [ebp+0x8]
0x7c8024f8 e88bf9ffff     call    0x7c801e88	; SYM:SleepEx#1E88
0x7c8024fd 5d             pop     ebp
0x7c8024fe c20400         ret     0x4
    ; *** SleepEx (858) ***
	; SYM:SleepEx#1E88
0x7c801e88 6a3c           push    0x3c
0x7c801e8a 684816827c     push    0x7c821648	; CODE(?):FF FF FF FF
0x7c801e8f e85dfb0100     call    0x7c8219f1
0x7c801e94 c745b424000000 mov     dword ptr [ebp-0x4c],0x24
0x7c801e9b c745b801000000 mov     dword ptr [ebp-0x48],0x1
0x7c801ea2 6a07           push    0x7
0x7c801ea4 59             pop     ecx
0x7c801ea5 33c0           xor     eax,eax
0x7c801ea7 8d7dbc         lea     edi,[ebp-0x44]
0x7c801eaa f3ab           rep     stosd
0x7c801eac 33f6           xor     esi,esi
0x7c801eae 39750c         cmp     [ebp+0xc],esi
0x7c801eb1 7547           jnz     0x7c801efa	; (*+0x49)
0x7c801eb3 8975fc         mov     [ebp-0x4],esi	; <==0x7C801F05(*+0x52)
0x7c801eb6 ff7508         push    dword ptr [ebp+0x8]
0x7c801eb9 8d45d8         lea     eax,[ebp-0x28]
0x7c801ebc 50             push    eax
0x7c801ebd e89cfa0100     call    0x7c82195e
0x7c801ec2 8945e4         mov     [ebp-0x1c],eax
0x7c801ec5 3bc6           cmp     eax,esi
0x7c801ec7 743e           jz      0x7c801f07	; (*+0x40)
0x7c801ec9 ff75e4         push    dword ptr [ebp-0x1c]	; <==0x7C801F17(*+0x4E), 0x7C801F20(*+0x57)
0x7c801ecc ff750c         push    dword ptr [ebp+0xc]
0x7c801ecf ff151815807c   call    dword ptr [0x7c801518]	; EXT:NTDLL.DLL!NtDelayExecution
0x7c801ed5 8945e0         mov     [ebp-0x20],eax
0x7c801ed8 39750c         cmp     [ebp+0xc],esi
0x7c801edb 753c           jnz     0x7c801f19	; (*+0x3E)
0x7c801edd 834dfcff       or      dword ptr [ebp-0x4],0xff	; <==0x7C801F1E(*+0x41)
0x7c801ee1 e848000000     call    0x7c801f2e
0x7c801ee6 b8c0000000     mov     eax,0xc0
0x7c801eeb 3945e0         cmp     [ebp-0x20],eax
0x7c801eee 7402           jz      0x7c801ef2	; (*+0x4)
0x7c801ef0 33c0           xor     eax,eax
0x7c801ef2 e835fb0100     call    0x7c821a2c	; <==0x7C801EEE(*-0x4)
0x7c801ef7 c20800         ret     0x8
;********************************************************************************
0x7c801efa 33d2           xor     edx,edx	; <==0x7C801EB1(*-0x49)
0x7c801efc 8d4db4         lea     ecx,[ebp-0x4c]
0x7c801eff ff155812807c   call    dword ptr [0x7c801258]	; EXT:NTDLL.DLL!RtlActivateActivationContextUnsafeFast
0x7c801f05 ebac           jmp     0x7c801eb3	; (*-0x52)
0x7c801f07 8975d8         mov     [ebp-0x28],esi	; <==0x7C801EC7(*-0x40)
0x7c801f0a c745dc00000080 mov     dword ptr [ebp-0x24],0x80000000
0x7c801f11 8d45d8         lea     eax,[ebp-0x28]
0x7c801f14 8945e4         mov     [ebp-0x1c],eax
0x7c801f17 ebb0           jmp     0x7c801ec9	; (*-0x4E)
0x7c801f19 3d01010000     cmp     eax,0x101	; <==0x7C801EDB(*-0x3E)
0x7c801f1e 75bd           jnz     0x7c801edd	; (*-0x41)
0x7c801f20 eba7           jmp     0x7c801ec9	; (*-0x57)
0x7c801f22 90             nop
0x7c801f23 90             nop
0x7c801f24 90             nop
0x7c801f25 90             nop
0x7c801f26 90             nop
0x7c801f27 33f6           xor     esi,esi
0x7c801f29 90             nop
0x7c801f2a 90             nop
0x7c801f2b 90             nop
0x7c801f2c 90             nop
0x7c801f2d 90             nop
0x7c801f2e 39750c         cmp     [ebp+0xc],esi	; <==0x7C801EE1(*-0x4D)
0x7c801f31 7501           jnz     0x7c801f34	; (*+0x3)
0x7c801f33 c3             ret	; <==0x7C801F3D(*+0xA)
;********************************************************************************
0x7c801f34 8d4db4         lea     ecx,[ebp-0x4c]	; <==0x7C801F31(*-0x3)
0x7c801f37 ff155412807c   call    dword ptr [0x7c801254]	; EXT:NTDLL.DLL!RtlDeactivateActivationContextUnsafeFast
0x7c801f3d ebf4           jmp     0x7c801f33	; (*-0xA)
hu7324829 2013-09-24
  • 打赏
  • 举报
回复
引用 4 楼 tony2278 的回复:
我同事碰到一个奇怪的现象:他在子线程里面 Sleep(1000); //但 现象是有时候会出现Sleep(5000)的效果。
即便是因为时间片原因没有及时解除阻塞, 也不可能到Sleep(5000)的效果, 我觉得还是你自己代码的问题.
ken_scott 2013-09-24
  • 打赏
  • 举报
回复
Windows的Sleep不会影响别的线程,(代码逻辑上引发的不论) Linux的sleep据说是进程相关的,推荐用nanosleep来做 (但我再ubuntu11.04下测试sleep,并非进程相关的)
lm_whales 2013-09-19
  • 打赏
  • 举报
回复
引用 5 楼 ananluowei 的回复:
[quote=引用 2 楼 tony2278 的回复:] 仅仅是会阻塞线程自身 1000ms?
是的,至少会阻塞1000ms,不影响其他线程 其他线程反而从中获得一定的利益,有1个线程在1000ms内不参与cpu时间片的竞争。[/quote] 如果各个线程,独立运行的话,那么什么问题也没有; 如果有同步,那么其它线程也会受到影响, 如果有消息处理,那么,消息会阻塞1秒---不知道有多少消息会阻塞, 如果有定时器,定时器又采用消息的方式, MFC定时器就是这样的,那么定时器也会阻塞, 如果定时器间隔较小,那么会有很多定时器时间到,的消息阻塞在这一秒--- Sleep的线程,什么也不做,那么如果占有其它线程需要的资源,必须等他1秒后醒来去处理, 只有释放了(至少等1秒),其他线程,才有机会得到资源。 Windows Sleep 不是必须的.
unituniverse2 2013-09-19
  • 打赏
  • 举报
回复
sleep和Sleep不一样
qq120848369 2013-09-18
  • 打赏
  • 举报
回复
The sleep() function shall cause the calling thread to be suspended from execution until either the number of realtime seconds specified by the argument seconds has elapsed or a signal is delivered to the calling thread and its action is to invoke a signal-catching function or to terminate the process. The suspension time may be longer than requested due to the scheduling of other activity by the system.
赵4老师 2013-09-18
  • 打赏
  • 举报
回复
检查是否资源泄漏的办法之一: 在任务管理器 进程 查看 选择列 里面选择:内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍,越多越好,比如1000000次甚至无限循环,记录以上各数值,再隔至少一小时,越长越好,比如一个月,再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加,则铁定有对应资源的资源泄漏! 《Windows核心编程》
unituniverse2 2013-09-18
  • 打赏
  • 举报
回复
引用 7 楼 tony2278 的回复:
子线程自身会出现先当于Sleep(5000)的效果,这种现象有可能1,2天都不会出现一次,有可能一个早上出现多次。
主板设计的问题
tony2278 2013-09-18
  • 打赏
  • 举报
回复
子线程自身会出现先当于Sleep(5000)的效果,这种现象有可能1,2天都不会出现一次,有可能一个早上出现多次。
max_min_ 2013-09-18
  • 打赏
  • 举报
回复
引用 2 楼 tony2278 的回复:
仅仅是会阻塞线程自身 1000ms?
其他影响目前我还没遇到过,或者可能没有影响到我的代码功能! 具体的得看看Sleep的源码已经和你的代码
大尾巴猫 2013-09-18
  • 打赏
  • 举报
回复
引用 2 楼 tony2278 的回复:
仅仅是会阻塞线程自身 1000ms?
是的,至少会阻塞1000ms,不影响其他线程 其他线程反而从中获得一定的利益,有1个线程在1000ms内不参与cpu时间片的竞争。
加载更多回复(4)

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧