Is it Really Busy Waiting If I Thread.Sleep()? - c#

My question is a bit nit-picky on definitions:
Can the code below be described as "busy waiting"? Despite the fact that it uses Thread.Sleep() to allow for context switching?
while (true) {
if (work_is_ready){
doWork();
}
Thread.Sleep(A_FEW_MILLISECONDS);
}
PS - The current definition for busy waiting in Wikipedia suggests that it is a "less wasteful" form of busy waiting.

Any polling loop, regardless of the time between polling operations, is a busy wait. Granted, sleeping a few milliseconds is a lot less "busy" than no sleep at all, but it still involves processing: thread context switches and some minimal condition checking.
A non-busy wait is a blocking call. The non-busy version of your example would involve waiting on a synchronization primitive such as an event or a condition variable. For example, this pseudocode:
// initialize an event to be set when work is ready
Event word_is_ready;
work_is_ready.Reset();
// in code that processes work items
while (true)
{
work_is_ready.Wait(); // non-busy wait for work item
do_work();
}
The difference here is that there is no periodic polling. The Wait call blocks and the thread is never scheduled until the event is set.

That's not busy waiting. Busy waiting, or spinning, involves the opposite: avoiding context switching.
If you want to allow other threads to run, if and only if other threads are ready to run, to avoid deadlock scenarios in single threaded CPUs (e.g., the current thread needs work_is_ready to be set to true, but if this thread doesn't give up the processor and lets others run, it will never be set to true), you can use Thread.Sleep(0).
A much better option would be to use SpinWait.SpinUntil
SpinWait.SpinUntil(() => work_is_ready);
doWork();
SpinWait emits a special rep; nop (repeat no-op) or pause instruction that lets the processor know you're busy waiting, and is optimized for HyperThreading CPUs.
Also, in single core CPUs, this will yield the processor immediately (because busy waiting is completely useless if there's only one core).
But spinning is only useful if you're absolutely sure you won't be waiting on a condition for longer than it would take the processor to switch the context out and back in again. I.e., no more than a few microseconds.
If you want to poll for a condition every few milliseconds, then you should use a blocking synchronization primitive, as the wiki page suggests. For your scenario, I'd recommend an AutoResetEvent, which blocks the thread upon calling WaitOne until the event has been signaled (i.e, the condition has become true).
Read also: Overview of Synchronization Primitives

It depends on the operating system and the exact number of milliseconds you are sleeping. If the sleep is sufficiently long that the operating system can switch to another task, populate its caches, and usefully run that task until your task is ready-to-run again, then it's not busy waiting. If not, then it is.
To criticize this code, I would say something like this: "This code may busy wait if the sleep is too small to allow the core to do useful work between checks. It should be changed so that the code that makes this code need to do work triggers that response."
This poor design creates a needless design problem -- how long should the sleep be? If it's too short, you busy wait. If it's too long, the work sits undone. Even if it's long enough that you don't busy wait, you force needless context switches.

When your code is sleeping for a moment, technically it will be in sleep state freeing up a CPU. While in busy waiting your code is holding the CPU until condition is met.
Can the code below be described as "busy waiting"? Despite the fact that it uses Thread.Sleep() to allow for context switching?
It is not busy waiting, rather polling which is more performant that busy waiting. There is a difference between both
Simply put, Busy-waiting is blocking where as Polling is non-blocking.

Busy waiting is something like this:
for(;;) {
if (condition) {
break;
}
}
The condition could be "checking the current time" (for example performance counter polling). With this you can get a very accurate pause in your thread. This is useful for example for low level I/O (toggling GPIOs etc.). Because of this your thread is running all the time, and if you are on cooperative multi threading, the you are fully in control, how long the thread will stay in that wait for you. Usually this kind of threads have a high priority set and are uninterruptible.
Now a non-busy waiting means, the thread is non-busy. It allows another threads to execute, so there is a context switch. To allow a context switch, in most languages and OS you can simply use a sleep(). There are another similar functions, like yield(), wait(), select(), etc. It depends on OS and language, if they are non-busy or busy implemented. But in my experience in all cases a sleep > 0 was always non-busy.
Advantage of non-busy waiting is allowing another threads to run, which includes idle threads. With this your CPU can go into power saving mode, clock down, etc. It can also run another tasks. After the specified time the scheduler tries to go back to your thread. But is is just a try. It is not exact and it may be a little bit longer, than your sleep defines.
I think. This is clear now.
And now the big question: Is this busy, or non-busy waiting:
for(;;) {
if (condition) {
break;
}
sleep(1);
}
The answer is: is is a non-busy waiting. sleep(1) allows the thread to perform a context-switch.
Now the next question: Is the second for() busy, or non-busy waiting:
function wait() {
for(;;) {
if (condition) {
break;
}
}
}
for(;;) {
wait();
if (condition) {
break;
}
sleep(1);
}
It is hard to say. It depends on the real execution time of the wait() function. If it does nothing, then the CPU is almost the entire time in sleep(1). And this would be a non-blocking for-loop. But if wait() is a heavy calculation function without allowing a thread context switch, then this whole for-loop may become a blocking function, even if there is a sleep(1). Think of the worst-case: the wait() function is never returning back to caller, because the condition isn't hit for a long time.
This here is hard to answer, because we don't know the conditions. You can imagine the problem, where you cannot answer the question, because you don't know the conditions, in the following way:
if (unkonwnCondition) {
for(;;) {
if (condition) {
break;
}
}
} else {
for(;;) {
if (condition) {
break;
}
sleep(1);
}
}
As you see, its the same: because you don't know the conditions, you cannot say if the wait is busy or non-busy.

Related

Are there performance differences between await Task.Delay() and Task.Delay().Wait() in a separate Task?

I have a construct like this:
Func<object> func = () =>
{
foreach(var x in y)
{
...
Task.Delay(100).Wait();
}
return null;
}
var t = new Task<object>(func);
t.Start(); // t is never awaited or waited for, the main thread does not care when it's done.
...
So basically i create a function func that calls Task.Delay(100).Wait() quite a few times. I know the use of .Wait() is discouraged in general.
But I want to know if there are concrete performance losses for the displayed case.
The .Wait() calls happen in a separate Task, that is completely independend from the main Thread, i.e. it is never awaited or waited for. I am curious what happens when I call Wait() this way, and what happens on the processor of my machine. During the 100 ms that are waited, can the processor core execute another thread, and returns to the Task after the time has passed? Or did I just produce a busy waiting procedure, where my CPU "actively does nothing" for 100 ms, thus slowing down the rest of my program?
Does this approach have any practical downsides when compared to a solution where i make it an async function and call await Task.Delay(100)? That would be an option for me, but I would rather not go for it if it is reasonably avoidable.
There are concrete efficiency losses because of the inefficient use of threads. Each thread requires at least 1 MB for its stack, so the more threads that are created in order to do nothing, the more memory is allocated for unproductive purposes.
It is also possible for concrete performance losses to appear, in case the demand for threads surpasses the ThreadPool availability. In this case the ThreadPool becomes saturated, and new threads are injected in the pool in a conservative (slow) rate. So the tasks you create and Start will not start immediately, but instead they will be entered in an internal queue, waiting for a free thread, either one that completed some previous work, or an new injected one.
Regarding your concerns about creating busy waiting procedures, no, that's not what happening. A sleeping thread does not consume CPU resources.
As a side note, creating cold Tasks using the Task constructor is an advanced technique that's only used in special occasions. The common way of creating delegate-based tasks is through the convenient Task.Run method, that returns hot (already started) tasks.

Delay and wake up a task from being executed? (Task.Delay?)

I have a situation where I have multiple threads being executed at once. In some cases these threads will be put in a while() loop for an unknown amount of time, and if a certain number of threads get caught in this loop then eventually the scheduler stops letting other threads be executed.
I was wondering if there is some way I could delay a thread from being executed (remove it from the scheduled list) and then let other threads in. Is it then possible to wake up that thread later by a threadID or something like that?
I am reading about Task.Delay and see it suspends execution from a timespan and that it is possible to time something out for an infinite amount of time, but is it possible to time it out indefinitely UNTIL a event occurs and then undelay it by some name or ID?
Edit: I thought this question was one that was harder to post code for, but more or less I have a situation where requests come in and are put into a loop like:
while(true){
//check for something that could make me want to delete this thread/request
//do some things
}
I had noticed that when I sent large number of requests that I never stopped ended up still in his loop (which I understand), but it seems the max amount of threads that could be doing this is 16/32 (depends on my computer that I run it on) and it is stopping other requests from being scheduled to run.
I wanted to know if inside the while() loop I could do something like this:
while(true){
//put this thread to sleep
//do some things that
//call some function to wake up the specific thread I need to do work on, before I put it back to sleep
}
The difference in this now is that instead of 16/32 threads running I can have 1 "king thread" that enters this while() loop that can 'do some things' and then wake up the thread that needs to be affected by the 'things'. Is there a way to sleep and wake up a specific thread so that other threads can be scheduled to run?
From the question I guess that you are running a busy waiting loop. That's pretty bad as you found out.
Make the loop wait for an event:
while (true) {
WaitForEvent();
DoWork();
}
This requires cooperation from the thread (or component) that makes the event happen. You could use a ManualResetEvent or a TaskCompletionSource to make this coordination happen.
I can't really be more specific because the question is not particularly concrete about the scenario. I hope this pushes you in the right direction.

Possible Race condition with ManualResetEvent

Problem:
I am trying to throw 6 threads from ThreadPool to work on individual tasks. Each task's ManualResetEvent is stored in a array of manual reset event. Number of thread corresponds to the index in the ManualResetEvent Array.
Now what happens is that once I have initiated these 6 threads I move out and wait for the threads to complete. Waiting for the thread is done in the main thread.
Now some times what happens is that my waiting logic doesn't return even after a long time (2 days that I have seen). Here is the code sample for thread wait logic
foreach (ManualResetEvent whandle in eventList)
{
try
{
whandle.WaitOne();
}
catch (Exception) { }
}
As per documentation of .WaitOne. It is sync call which makes the thread to not return if Set event is not received from the thread.
Sometimes my threads have less amount of work and they may even return before I reach the Wait logic. Is it possible that .WaitOne() will wait for the Set() event even if it was received in the past?
Is this a correct logic to wait for the all the threads to close?
I'm not directly answering this question. Here is what you should do:
Start tasks using Task.Factory.StartNew and use Task.WaitAll(Task[]) to wait for them. You do not have to deal with events that way. Exceptions will nicely propagate to the "forking" thread. You don't need the old ThreadPool API anymore.
Hope this helps.
(Note: I think your best bet is Parallel.Invoke() - see later in this answer.)
What you are doing will normally work fine, so the problem is likely to be that one of your threads is blocking for some reason.
You should be able to debug this readily enough - you can attach the debugger and break into the program and then look at the call stack to see which thread(s) are blocked. Be prepared for some head-scratching if you discover a race condition though!
Another thing to be aware of that you can't do the following:
myEvent.Set();
myEvent.Reset();
with nothing (or very little) between the .Set() and the .Reset(). If you do that when several threads are waiting on myEvent, some of them will miss the event being set! (This effect is not well documented on MSDN.)
By the way, you shouldn't ignore exceptions - always log them in some way, at the very least.
(This section doesn't answer the question, but it may provide some helpful information)
I also want to mention an alternative way to wait for the threads. Since you have a set of ManualResetEvents, you can copy them to a plain array and pass it to WaitHandle.WaitAll().
Your code could look a little like this:
WaitHandle.WaitAll(eventList.ToArray());
Another approach to waiting for all threads to finish is to use a CountdownEvent. It becomes signalled when a countdown reaches zero; you start the count at the number of threads, and each thread signals it when it exits. There's an example here.
Parallel.Invoke()
If your threads do not return values, and all you want to to is to launch them and then have the launching thread wait for them to exit, then I think Parallel.Invoke() will be the best way of all. It avoids you having to handle the synchronization yourself.
(Otherwise, as svick says in the comments above, use Task rather than the old thread classes.)

SpinWait vs Sleep waiting. Which one to use?

Is it efficient to
SpinWait.SpinUntil(() => myPredicate(), 10000)
for a timeout of 10000ms
or
Is it more efficient to use Thread.Sleep polling for the same condition
For example something along the lines of the following SleepWait function:
public bool SleepWait(int timeOut)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (!myPredicate() && stopwatch.ElapsedMilliseconds < timeOut)
{
Thread.Sleep(50)
}
return myPredicate()
}
I'm concerned that all the yielding of SpinWait may not be a good usage pattern if we are talking about timeouts over 1sec? Is this a valid assumption?
Which approach do you prefer and why? Is there another even better approach?
Update - Becoming more specific:
Is there a way to Make BlockingCollection Pulse a sleeping thread when it reaches bounded capacity? I rather avoid a busy waits alltogether as Marc Gravel suggests.
In .NET 4 SpinWait performs CPU-intensive spinning for 10 iterations before yielding. But it does not return to the caller immediately after each of those cycles; instead, it calls Thread.SpinWait to spin via the CLR (essentially the OS) for a set time period. This time period is initially a few tens of nano-seconds but doubles with each iteration until the 10 iterations are complete. This enables clarity/predictability in the total time spent spinning (CPU-intensive) phase, which the system can tune according to conditions (number of cores etc.). If SpinWait remains in the spin-yielding phase for too long it will periodically sleep to allow other threads to proceed (see J. Albahari's blog for more information). This process is guaranteed to keep a core busy...
So, SpinWait limits the CPU-intensive spinning to a set number of iterations, after which it yields its time slice on every spin (by actually calling Thread.Yield and Thread.Sleep), lowering its resource consumption. It will also detect if the user is running a single core machine and yield on every cycle if that is the case.
With Thread.Sleep the thread is blocked. But this process will not be as expensive as the above in terms of CPU.
The best approach is to have some mechanism to actively detect the thing becoming true (rather than passively polling for it having become true); this could be any kind of wait-handle, or maybe a Task with Wait, or maybe an event that you can subscribe to to unstick yourself. Of course, if you do that kind of "wait until something happens", that is still not as efficient as simply having the next bit of work done as a callback, meaning: you don't need to use a thread to wait. Task has ContinueWith for this, or you can just do the work in an event when it gets fired. The event is probably the simplest approach, depending on the context. Task, however, already provides most-everything you are talking about here, including both "wait with timeout" and "callback" mechanisms.
And yes, spinning for 10 seconds is not great. If you want to use something like your current code, and if you have reason to expect a short delay, but need to allow for a longer one - maybe SpinWait for (say) 20ms, and use Sleep for the rest?
Re the comment; here's how I'd hook an "is it full" mechanism:
private readonly object syncLock = new object();
public bool WaitUntilFull(int timeout) {
if(CollectionIsFull) return true; // I'm assuming we can call this safely
lock(syncLock) {
if(CollectionIsFull) return true;
return Monitor.Wait(syncLock, timeout);
}
}
with, in the "put back into the collection" code:
if(CollectionIsFull) {
lock(syncLock) {
if(CollectionIsFull) { // double-check with the lock
Monitor.PulseAll(syncLock);
}
}
}

Purpose of Thread.Sleep(1)?

I was reading over some threading basics and on the msdn website I found this snippet of code.
// Put the main thread to sleep for 1 millisecond to
// allow the worker thread to do some work:
Thread.Sleep(1);
Here is a link to the the page: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.80).aspx.
Why does the main thread have sleep for 1 millisecond? Will the secondary thread not start its tasks if the main thread is continuously running? Or is the example meant for a task that takes 1 millisecond to do? As in if the task generally takes 5 seconds to complete the main thread should sleep for 5000 milliseconds?
If this is solely regarding CPU usage, here is a similar Question about Thread.Sleep.
Any comments would be appreciated.
Thanks.
The 1 in that code is not terribly special; it will always end up sleeping longer than that, as things aren't so precise, and giving up your time slice does not equal any guarantee from the OS when you will get it back.
The purpose of the time parameter in Thread.Sleep() is that your thread will yield for at least that amount of time, roughly.
So that code is just explicitly giving up its time slot. Generally speaking, such a bit of code should not be needed, as the OS will manage your threads for you, preemptively interrupting them to work on other threads.
This kind of code is often used in "threading examples", where the writer wants to force some artificial occurrence to prove some race condition, or the like (that appears to be the case in your example)
As noted in Jon Hanna's answer to this same question, there is a subtle but important difference between Sleep(0) and Sleep(1) (or any other non-zero number), and as ChrisF alludes to, this can be important in some threading situations.
Both of those involve thread priorities; Threads can be given higher/lower priorities, such that lower priority threads will never execute as long as there are higher priority threads that have any work to do. In such a case, Sleep(1) can be required... However...
Low-priority threads are also subject to what other processes are doing on the same system; so while your process might have no higher-priority threads running, if any others do, yours still won't run.
This isn't usually something you ever need to worry about, though; the default priority is the 'normal' priority, and under most circumstances, you should not change it. Raising or lowering it has numerous implications.
Thread.Sleep(0) will give up the rest of a thread's time-slice if a thread of equal priority is ready to schedule.
Thread.Sleep(1) (or any other value, but 1 is the lowest to have this effect) will give up the rest of the thread's time-slice unconditionally. If it wants to make sure that even threads with lower priority have a chance to run (and such a thread could be doing something that is blocking this thread, it has to), then it's the one to go for.
http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54b8f3d1a1.aspx has more on this.
If the main thread doesn't sleep at all then the other threads will not be able to run at all.
Inserting a Sleep of any length allows the other threads some processing time. Using a small value (of 1 millisecond in this case) means that the main thread doesn't appear to lock up. You can use Sleep(0), but as Jon Hanna points out that has a different meaning to Sleep(1) (or indeed any positive value) as it only allows threads of equal priority to run.
If the task takes 5 seconds then the main thread will sleep for a total of 5,000 milliseconds, but spread out over a longer period.
It's only for the sake of the example- they want to make sure that the worker thread has the chance to print "worker thread: working..." at least once before the main thread kills it.
As Andrew implied, this is important in the example especially because if you were running on a single-processor machine, the main thread may not give up the processor, killing the background thread before it has a chance to iterate even once.
Interesting thing I noticed today. Interrupting a thread throws a ThreadInterruptedException. I was trying to catch the exception but could not for some reason. My coworker recommended that I put Thread.Sleep(1) prior to the catch statement and that allowed me to catch the ThreadInterruptedException.
// Start the listener
tcpListener_ = new TcpListener(ipAddress[0], int.Parse(portNumber_));
tcpListener_.Start();
try
{
// Wait for client connection
while (true)
{
// Wait for the new connection from the client
if (tcpListener_.Pending())
{
socket_ = tcpListener_.AcceptSocket();
changeState(InstrumentState.Connected);
readSocket();
}
Thread.Sleep(1);
}
}
catch (ThreadInterruptedException) { }
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Contineo", MessageBoxButtons.OK, MessageBoxIcon.Error);
Console.WriteLine(ex.StackTrace);
}
Some other class...
if (instrumentThread_ != null)
{
instrumentThread_.Interrupt();
instrumentThread_ = null;
}

Categories

Resources