Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Sleep block program exit? How is it implemented?

In a single-threaded console application, people often use Thread.Sleep as a lazy way to pause the application for some time.

This question raised interesting points about NOT using this approach: Why is Thread.Sleep so harmful

However other than knowing that Sleep blocks the current thread, I don't understand how it works - for instance does it max out the CPU core in a tight loop or does it actually pause the thread?

More importantly to me, how does a console app respond to various app-exit scenarios (CTRL-C, kill, window close button) when caught in the middle of a Sleep? Will it blindly continue executing until the OS force-kills it, or will it behave well?

like image 738
Mr. Boy Avatar asked Jun 06 '16 16:06

Mr. Boy


People also ask

Does sleep block a process?

Sleep blocks all execution, but only in the thread from which you call it.

Does sleep block the thread?

Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. Once that interval elapses, the sleeping thread resumes execution. One thread cannot call Thread.

What happens when a thread sleeps?

Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.

Does thread sleep cause context switch?

Every time we deliberately change a thread's status or attributes (e.g. by sleeping, waiting on an object, changing the thread's priority etc), we will cause a context switch.


2 Answers

This is more of an OS question than a C#/.NET related question, but I'll try and answer succinctly.

Thread.Sleep will not spin lock your CPU, instead it will call the appropriate mechanism in the underlying OS to suspend your thread. On windows, that function is described here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx

Using this normal system call your thread cannot be rescheduled until the timeout has elapsed. Forcefully killing the thread (or the entire process) is then required.

When you hit ctrl+c in cmd.exe, the console spawns a new thread in each process attached to handle the event (Described here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682541(v=vs.85).aspx). Because of this, your program as a whole will still "behave well" when you hit ctrl+c, but your sleeping thread itself will wind up being killed prematurely.

like image 86
Michael Sondergaard Avatar answered Oct 13 '22 00:10

Michael Sondergaard


This is source code of Thread.Sleep method:

[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();
}

As we can see this method calls Thread.SleepInternal method. In comment about it we can read that this method suspends the current thread for timeout milliseconds. Next, we can read that if timeout == 0 then this method forces the thread to give up the remainder of its timeslice and if timeout equals Timeout.Infinite then no timeout will occur. I recommend you reading about multithreading and application lifecycle (in this case especially suspended).

Links:

  • https://msdn.microsoft.com/en-us/library/ms900951.aspx
  • https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/app-lifecycle
like image 41
hubot Avatar answered Oct 12 '22 22:10

hubot