在Windows下使用VC ++ 13,在线帮助指出使用Sleep(0)将当前线程时间片的剩余部分放弃到具有相同优先级的任何其他线程。其他价值也是如此吗?例如如果我使用Sleep(1000)是1000毫秒的CPU时间,当前线程运行的核心可能被另一个线程使用?我想这是硬件和实现特定的,所以要缩小它,假设Intel I5或更好,Windows 7或8。
询问的原因是我有一个线程池类,我使用额外的监视器线程来报告进度,允许用户中止长进程等...
答案 0 :(得分:3)
是的,零具有特殊意义,仅用于表示没有最短的等待时间。通常情况下它可以解释为"我想要在没有时间睡觉#34;这没有多大意义。这意味着"我想给其他线程运行机会。"
如果它不为零,则保证线程不会在指定的时间内返回,当然在时钟分辨率内。当线程被挂起时,它在系统中获得挂起状态,在调度期间不予考虑。使用0
时,它不会改变它的状态,因此它仍然可以运行,并且该功能可能会立即返回。
另外,我不认为它与硬件有关,这纯粹是系统级的事情。
答案 1 :(得分:1)
值为零会导致线程将其时间片的剩余部分放弃到准备运行的任何其他线程。如果没有其他线程准备好运行,则该函数立即返回,并且线程继续执行。
特殊的XP案例描述如下:
Windows XP:值为零会导致线程将其时间片的剩余部分放弃到准备运行的任何其他具有相同优先级的线程。如果没有其他具有相同优先级的线程准备运行,则该函数立即返回,并且线程继续执行。从Windows Server 2003开始,此行为已更改。
MSDN声明线程时间片的提醒被放弃到任何其他具有相同优先级的线程。这有点无意义,因为在线程调用Sleep(0)
之前已经调度了具有更高优先级的线程,并且具有较低优先级的线程将导致Sleep(0)
立即返回而不给出任何东西。因此,Sleep(0)
默认情况下仅对具有相同优先级的线程产生影响。
Sleep(0)
的目的:它触发调度程序重新调度,同时将调用线程放在队列的末尾。如果队列没有任何其他具有相同优先级的进程,则呼叫将立即返回。如果有其他线程,则延迟未确定。注意:Windows调度程序不是单个线程,它遍布整个操作系统(详细信息:How does a scheduler regain control when wanted?)。
详细行为取决于系统计时器分辨率设置(How to get the current Windows system-wide timer resolution)。此设置也会影响线程时间片,它随系统计时器分辨率而变化。
系统计时器分辨率定义系统的心跳。这会导致线程量子具有特定值。计时器分辨率粒度也决定了Sleep(period)
的分辨率。因此,睡眠周期的准确性由系统心跳确定。但是,高分辨率定时器设置会增加功耗。
Sleep(period)
周期> 0触发调度程序并禁止为至少所请求的时间段调度调用线程。
因此,调用线程时间片被中断。它立即结束。
是,Sleep(period)
期间> 0将CPU时间放弃到其他线程(如果适用)。
(进一步阅读:Few words about timer resolution,How to get an accurate 1ms Timer Tick under WinXP和Limits of Windows Queue Timers)。