Thread.Sleep(1)在C#中有什么影响?

Jus*_*ner 29 c# multithreading

在Windows窗体应用程序中,调用的影响Thread.Sleep(1)如下面的代码所示:

public Constructor()
{
    Thread thread = new Thread(Task);
    thread.IsBackground = true;
    thread.Start();
}

private void Task()
{
    while (true)
    {
        // do something
        Thread.Sleep(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个线程会占用所有可用的CPU吗?

我可以使用哪些分析技术来测量此线程的CPU使用率(除了任务管理器)?

Bob*_*ler 43

如上所述,您的循环不会占用CPU.

但请注意:Windows 不是实时操作系统,因此您不会从Thread.Sleep(1)获得每秒1000次的唤醒.如果你还没有使用timeBeginPeriod来设置你的最低分辨率,你将每15毫秒唤醒一次.即使您将最小分辨率设置为1 ms,您仍然只会每3-4毫秒唤醒一次.

为了获得毫秒级别的计时器粒度,您必须使用Win32多媒体计时器(C#wrapper).

  • http://www.pinvoke.net/default.aspx/winmm.timeBeginPeriod根据MSDN文档,timeBeginPeriod应与timeEndPeriod调用匹配.另请注意"此功能会影响全局Windows设置." 并可能影响系统性能. (3认同)

Fre*_*ool 28

不,它不会占用CPU,它会暂停你的线程至少那么久.当您的线程暂停时,操作系统可以安排另一个不相关的线程来使用处理器.

  • 在现代CPU上,与使用i ++相比,1ms的睡眠是永恒的. (8认同)

Jor*_*oba 19

Thread.Sleep(1)如上所述不会占用CPU.

以下是线程休眠时(或多或少)发生的情况:

  • Thread.Sleep被转换为系统调用,进而触发陷阱(允许操作系统控制的中断)
  • 操作系统检测到睡眠调用并将您的线程标记为已阻止.
  • 在内部,操作系统会保留一个需要唤醒的线程列表以及何时应该被唤醒.
  • 由于线程不再使用CPU OS ...
  • 如果父进程没有用完所有时间片,则OS将调度该进程的另一个线程以供执行.
  • 否则,另一个进程(或空闲进程)将开始执行.
  • 当时间到期时,您的线程将再次被安排执行,这并不意味着它将自动开始执行.

最后一点,我并不完全知道你在做什么,但似乎你正试图扮演调度程序的角色,也就是说,睡觉为CPU提供时间做其他事情......

在少数情况下(确实很少)它可能是正确的,但大多数情况下你应该让调度程序完成它的工作,它可能比你知道的更多,并且可以使工作比你做的更好.


小智 5

应该避免小的睡眠时间,因为放弃其时间片的线程在重新发出信号时会获得优先级提升,这可能导致高上下文切换。在多线程/服务器应用程序中,这可能会导致抖动效果,因为线程正在争夺 CPU 时间。相反,依靠异步函数和同步对象,例如临界区或互斥体/信号量。