【问题标题】:Does Sleep block program exit? How is it implemented?睡眠阻止程序是否退出?它是如何实施的?
【发布时间】:2016-06-06 16:47:48
【问题描述】:

在单线程控制台应用程序中,人们经常使用Thread.Sleep 作为一种懒惰的方式来暂停应用程序一段时间。

这个问题提出了关于不使用这种方法的有趣观点:Why is Thread.Sleep so harmful

但是,除了知道 Sleep 会阻塞当前线程之外,我不明白它是如何工作的 - 例如,它是在一个紧密的循环中最大化 CPU 内核还是实际上暂停了线程?

对我来说更重要的是,控制台应用程序在睡眠过程中如何响应各种应用程序退出场景(CTRL-C、kill、窗口关闭按钮)?它会盲目地继续执行直到操作系统强制杀死它,还是会表现良好?

【问题讨论】:

  • 它只是告诉操作系统的线程调度程序不要重新调度线程以在指定的时间内执行。可以肯定的是,它已“暂停”。控制台终止由操作系统实现,并简单地终止进程。无论进程中的线程在做什么都是无关紧要的,它们不再是挪威鹦鹉式的。
  • 有兴趣的可以看implementation for Thread.Sleep() here
  • 感谢@HansPassant 'suspended' 是我想要的术语——因为 Sheeo 明确指出线程被挂起而不是导致自旋锁。不错的 MP 参考。
  • 嗯,不,这不是您想要的术语。挂起的线程与 Sleep() 没有任何关系。但是话又说回来,任何使用 SuspendThread() 的人都应该受到他们将得到的所有痛苦。
  • 现在我很困惑@HansPassant,因为Sleep 的文档说“Sleep 函数 - 暂停当前线程的执行,直到超时间隔已过”(msdn.microsoft.com/en-us/library/windows/desktop/…)您介意在答案中澄清这一点吗?

标签: c# .net multithreading thread-sleep


【解决方案1】:

这更像是一个操作系统问题,而不是 C#/.NET 相关问题,但我会尽量简洁地回答。

Thread.Sleep 不会自旋锁定您的 CPU,而是会调用底层操作系统中的适当机制来挂起您的线程。在 Windows 上,该功能在此处描述:https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx

使用这个正常的系统调用,你的线程在超时之前不能被重新调度。然后需要强制终止线程(或整个进程)。

当您在 cmd.exe 中按 ctrl+c 时,控制台会在每个附加的进程中生成一个新线程来处理事件(此处描述:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682541(v=vs.85).aspx)。因此,当您按下 ctrl+c 时,您的程序作为一个整体仍然会“表现良好”,但您的睡眠线程本身会过早地被杀死。

【讨论】:

    【解决方案2】:

    这是Thread.Sleep方法的源代码:

    [System.Security.SecuritySafeCritical]  // auto-generated
    public static void Sleep(int millisecondsTimeout)
    {
        SleepInternal(millisecondsTimeout);
        // Ensure we don't return to app code when the pause is underway
        if(AppDomainPauseManager.IsPaused)
            AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
    }
    

    我们可以看到这个方法调用了 Thread.SleepInternal 方法。在对此的评论中,我们可以读到此方法将当前线程挂起超时毫秒。接下来,我们可以读到如果 timeout == 0 则此方法强制线程放弃其时间片的剩余部分,如果 timeout 等于 Timeout.Infinite 则不会发生超时。我建议您阅读有关多线程和应用程序生命周期(在这种情况下尤其是暂停)的内容。

    链接:

    【讨论】:

    • 第一个链接适用于 windows CE - 可能不是 OP 使用的
    • @pm100:这个链接或多或少地向他介绍了it方法的工作原理。
    猜你喜欢
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多