Программа блокировки сна выходит? Как это реализовано?

В однопоточном консольном приложении люди часто используют Thread.Sleep как ленивый способ приостановить приложение на некоторое время.

Этот вопрос поднял интересные моменты относительно НЕ использования этого подхода: Почему Thread.Sleep так вреден

Однако, кроме того, что я знаю, что Sleep блокирует текущий поток, я не понимаю, как это работает - например, он максимально использует ядро ​​ЦП в жестком цикле или фактически приостанавливает поток?

Что еще более важно для меня, как консольное приложение реагирует на различные сценарии выхода из приложения (CTRL-C, kill, кнопка закрытия окна), когда оно застряло в середине сна? Будет ли он слепо продолжать выполнение, пока ОС не убьет его принудительно, или он будет вести себя хорошо?


person Mr. Boy    schedule 06.06.2016    source источник
comment
Он просто сообщает планировщику потоков операционной системы, чтобы он не перепланировал выполнение потока на указанный период времени. Конечно, это приостановлено. Консольные убийства реализуются ОС и просто завершают процесс. Что бы ни делали нити в процессе, это не актуально, они перестают быть норвежским попугаем.   -  person Hans Passant    schedule 06.06.2016
comment
Тем, кому интересно, вы можете увидеть реализацию для _1 здесь.   -  person Rion Williams    schedule 06.06.2016
comment
Спасибо @HansPassant «приостановлено» - это термин, который я хотел, поскольку Sheeo явно указывает, что поток приостановлен, а не приводит к блокировке вращения. Хорошая ссылка на депутата.   -  person Mr. Boy    schedule 06.06.2016
comment
Хм, нет, это не тот термин, который вам нужен. Приостановленный поток не имеет ничего общего с Sleep (). Но опять же, любой, кто использует SuspendThread (), заслуживает всех страданий, которые он получит.   -  person Hans Passant    schedule 06.06.2016
comment
Теперь я запутался в @HansPassant, потому что в документации Sleep говорится, что функция Sleep - приостанавливает выполнение текущего потока до тех пор, пока не истечет интервал времени ожидания (msdn.microsoft.com/en-us/library/ windows / desktop /) Не могли бы вы пояснить это в ответе?   -  person Mr. Boy    schedule 06.06.2016


Ответы (2)


Это скорее вопрос ОС, чем вопрос, связанный с C # /. NET, но я постараюсь ответить кратко.

Thread.Sleep не будет вращать блокировку вашего процессора, вместо этого он вызовет соответствующий механизм в базовой ОС, чтобы приостановить ваш поток. В Windows эта функция описана здесь: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx

Используя этот обычный системный вызов, ваш поток не может быть перепланирован, пока не истечет время ожидания. Затем требуется принудительное завершение потока (или всего процесса).

Когда вы нажимаете ctrl + c в cmd.exe, консоль порождает новый поток в каждом процессе, прикрепленном для обработки события (Описано здесь: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682541(v=vs.85).aspx ). Из-за этого ваша программа в целом будет по-прежнему «вести себя хорошо», когда вы нажмете ctrl + c, но сам ваш спящий поток будет преждевременно завершен.

person Michael Sondergaard    schedule 06.06.2016

Это исходный код метода 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, то таймаут не произойдет. Рекомендую прочитать про многопоточность и жизненный цикл приложения (в данном случае особенно приостановленного).

Ссылки:

person hubot    schedule 06.06.2016
comment
первая ссылка предназначена для Windows CE - вероятно, не то, что использует OP - person pm100; 06.06.2016
comment
@ pm100: Эти ссылки должны более или менее познакомить его с тем, как работает этот метод. - person hubot; 06.06.2016