Is Thread.Sleep (1) special?

Joe Duffy (author of Parallel Programming on Windows ) writes in this blog article that Thread.Sleep (1) is preferred over Thread.Sleep (0) because it will pause for threads with one or lower priority. and not just equal priority threads, as for Thread.Sleep (0).

. The MSDN NET version says that Thread.Sleep (0) is special, it pauses this thread and allows other pending threads to execute. But it does not say anything about Thread.Sleep (1) (for any version of .NET).

So, does Thread.Sleep (1) really do something special?

Background:

I am updating my knowledge of parallel programming. I wrote C # code to illustrate that the pre / post increments and decrements are not atomic and therefore are not thread safe.

To avoid the need to create hundreds of threads, I put Thread.Sleep (0) after increasing the shared variable to force the scheduler to start another thread. This regular replacement of flows makes the non-atomic nature before / after increment / decrease more obvious.

Thread.Sleep (0) does not seem to cause additional delay, as expected. However, if I changed this to Thread.Sleep (1), it seems to return to normal sleep mode (for example, I get about a minimum of 1 ms delay).

This will mean that although Thread.Sleep (1) might be preferable, any code that uses it in a loop will run much slower.

This SO question is "Can someone explain this interesting behavior with Sleep (1)?" is kind of relevant, but it focuses on C ++ and just repeats the tutorial in Joe Daffy's blog post.

Here is my code for anyone interested (copied from LinqPad, so you might need to add a class around it):

int x = 0; void Main() { List<Thread> threadList=new List<Thread>(); Stopwatch sw=new Stopwatch(); for(int i=0; i<20; i++) { threadList.Add(new Thread(Go)); threadList[i].Priority=ThreadPriority.Lowest; } sw.Start(); foreach (Thread thread in threadList) { thread.Start(); } foreach (Thread thread in threadList) { thread.Join(); } sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); Thread.Sleep(200); Console.WriteLine(x); } void Go() { for(int i=0;i<10000;i++) { x++; Thread.Sleep(0); } } 
+42
multithreading c #
May 16 '13 at 9:58
source share
1 answer

You no longer need to use Sleep(1) instead of Sleep(0) because Microsoft has changed the implementation of the Windows API Sleep() .

From the MSDN documentation for Sleep () , here's what happens with Sleep (0) now:

A value of zero causes the thread to discard the remainder of its temporary fragment to any other thread that is ready to start. If there are no other threads ready to start, the function returns immediately and the thread continues execution.

This is what used to happen in Windows XP:

A value of zero causes the thread to discard the remainder of its time slice to any other thread with equal priority that is ready to run. If there are no other threads of equal priority ready to start, the function returns immediately and the thread continues execution. This behavior has changed since Windows Server 2003.

Note the difference between "any other thread" and "any other thread with equal priority."

The only reason Joe Duffy suggests using Sleep (1) rather than Sleep (0) is because it is the shortest Sleep () value that will not allow Sleep () to return immediately if there are no other threads with equal priority ready to run when running on Windows XP.

You do not need to worry about this for OS versions after Windows Server 2003 due to a change in Sleep () behavior.

I draw your attention to this part of Joe's blog:

And even if there is a clear dream, giving it out does not allow the producer to plan, because he has a lower priority.

In XP, threads with a lower priority will starve even if the main thread (with a higher priority) does Sleep (0). Post-XP, this will not happen anymore, because Sleep (0) will allow you to run threads with a lower priority.

+53
May 16 '13 at 10:09
source share



All Articles