Keep threads idle or kill them / restart them? - c#

Pseudo-situation: have a class (let's say BackgroundMagic), and it has Start() and Stop() methods. The work in this class is done by one single thread, and is simply a short loop every X milliseconds.
Which of these options is better, as far as managing the stopping/starting? Can't decide which road to take.
The first time Start() is called, initialize and start the thread with IsBackground = true. Use a simple bool flag to indicate on each loop around whether it should actually do any work, or just sleep. After initial initialization, let Stop() and Start() simply control the bool flag. The thread will just be stopped and cleaned up by the runtime since IsBackground = true when the app exits.
Forcefully abort/join/interrupt/whatever on Stop, and recreate the thread again on Start(), not leaving the thread lying around.
... or any better/cleaner ways of doing this?

Neither! Use a Thread Pool!

Thread creation is fairly expensive, so the standard "industrial-strength" way to do this is to control the thread with a flag. For a larger-scale variant on the same idea, consider the thread pools that e.g. Apache uses to manage thousands of threads without a lot of explicit state or a painful performance hit.
So in the abstract, I'd vote for your option #1. But if performance isn't a concern and the option #2 code is easier to reason about, go for it.

A mutex or semaphore would be a better option than a simple boolean flag, because it doesn't require checking the state of the flag repeatedly. Simply block on the mutex/semaphore, and when you want the thread to run, release the mutex/semaphore and the thread will run once.

The thread pool is not appropriate for long-running tasks. The thread pool is ideal for short tasks where the overhead of thread creation increases the overhead of the operation by a large percentage. This is also true of the TPL (Task Parallel Library) in the .NET 4 framework.
Using a thread dedicated to do this work is probably a good idea, but how you manage it can be a big deal. If you simply do a Thread.Sleep between checking for work then that is less effective because now you have the thread spinning for no good reason. This is called a spin lock (kind of) and is only effective if you know the resource you are waiting for is going to release the lock very soon. It would be a far better idea to use an AutoResetEvent. This way the thread only wakes up because the producer thread signaled that there is work to do. This has the advantage of not wasting CPU resources to schedule the thread if there is nothing to do and it allows for less delay between the producer and consumer.
To answer your question directly, yes you can use some kind of bool to gracefully shutdown the thread (I would mark it as volatile though). This is much better than aborting the thread!
See:
http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml
http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx

You can also use a bool flag to indicate if the thread should stop. Which gives you your interrupt and stop code. So two bools one for if there is work and one to stop the loop.
The other thing you could consider is using the Dispose pattern and cleaning up the thread when the object is disposed.

I would use the bool flag, but you need to be sure it is either correctly locked or only set from one thread. Your loop should look like this
while (true)
{
if (shouldSleep)
{
Thread.Sleep(interval);
continue;
}
doSomeWork();
if (shouldCancel)
{
CleanUpResources();
break;
}
}
This makes sure you can send the thread to sleep but also correctly terminate it. Killing a thread is never a good idea if you can avoid it as the thread doesn't have a chance to clean up any resources used. You need to decide on an appropriate sleep interval though. It will determine the latency your thread needs to start up.
The second option is rather expensive, thread creation involves some OS resources and startup time is also considerable. If thread recreation won't happen often and the amount of work performed is large enough this would be reasonable. You can avoid the complexity involved in the loop approach.

Related

How to "Free" a thread

I have 20 threads running at a time in my program, (create 20 wait for them to finish, start another 20), after a while my program slows way down. Do I need to free the tasks or do anything special? If so how, if not is there a common reason why a program like this would slow down?
You might want to consider using the ThreadPool, either directly, or via the Task Parallel Library (my preferred option). This is likely a better, simpler, and cleaner design than spawning your own threads and blocking on them repeatedly.
That being said, if your program is getting progressively slower, this is something where a profiler can help dramatically. Without seeing code, it's very difficult to diagnose. For example, depending on the work that you're doing, you may be causing the GC to become less efficient over time, which could cause the % of time spent in GC to climb as the program continues its execution. Profiling should give you a good indication of what is taking time as your program executes.
Reed's answer is probably the best way to deal with your issue; however, if you do want to manage the threads yourself, and not use the ThreadPool or TPL, I'd have to ask why you would let 20 threads die and create 20 more. Creating threads is an expensive process, which is why the thread pool exists. If you continually have the same number of parallel tasks, or a maximum number, they should be created once and reused. You can use locking constructs such as semaphore and mutex and have the threads wait when they are done, and just give them new data to work with and release them to proceed again. Waiting on a lock is a very inexpensive operation -- orders of magnitude cheaper than recreating a thread.
So for example, a thread might look like this (pseudocode):
while (program_not_ending)
{
wait_for_new_data_release; // Wait on thread's personal mutex
process_new_data;
resignal_my_mutex; // Cause the beginning of loop to wait again
release_semaphore_saying_I_am_done; // Increment parent semaphore count
}
The parent would then wait for its semaphore to fill up that 20 threads completed, reset the data buckets, and clear all of the thread mutexes.

Waiting thread count and working thread count on Semaphore

Is there any way to find that
how many threads are waiting on semaphore?
how many threads have currently occupied semaphore?
if i use threadpool thread to wait on semaphore, how to let main thread wait until threadpool thread is finished.
Thanks.
This is forbidden knowledge in thread synchronization. Because it is utterly impossible to ever make this accurate. It represents an unsolvable race condition. When you use Habjan's approach, you'll conclude that there are, say, two threads waiting. A microsecond later another thread calls WaitOne() and there are three. But you'll make decisions based on that stale value.
Race conditions are nothing to mess with, they are incredibly hard to debug. They have a habit of making your code fail only once a week. As soon as you add instrumenting code to try to diagnose the reason your code fails, they'll stop occurring because that added code changed the timing.
Never do this.

Best way: to implement an interrupt/cancel feature for all your threaded workers

So my question is how to implement cancel/interrupt feature into all (I mean ALL) thread workers in your application in best and most elegant way?
It's not important if it's an HttpWebRequest, IO operation or calculation. User should have an possibility to cancel every action/thread at any moment.
Use .NET 4.0 Tasks with CancellationTokens - they are the new universal cancellation system.
User should have an possibility to
cancel every action/thread at any
moment.
Threading is a practice, not a design... and believe me it has been tried as a design, but it failed miserably. The basic problem with simply canceling any action at any moment is that in a multithreaded environment it's just evil! Imagine that you have a section of code guarded by a lock and you have two threads running in parallel:
Thread 1 acquires the lock.
Thread 2 waits until the lock is released so it can acquire it.
Thread 1 is canceled while it's holding the lock and it doesn't release the lock.
DEADLOCK: Thread 2 is waiting for the lock which will never be released.
This is the simplest example and technically we can take care of this situation in the design, i.e. automatically release any locks that the thread has acquired, but instead of locks think of object states, resource utilization, client dependencies, etc. If your thread is modifying a big object and it's canceled in the middle of the modification, then the state of the object may be inconsistent, the resource which you're utilizing might get hung up, the client depending on that thread might crash... there is a slew of things which can happen and there is simply no way to design for them. In this case you make it a practice to manage the threads: you ensure a safe cancellation of your threads.
Others have already mentioned various methods for starting threads that can be canceled, but I just wanted to touch on the principles. Even in the cases where there is a way to cancel your threads, you still have to keep in mind that you're responsible for determining the safest way to cancel your thread.
It's not important if it's an HttpWebRequest, IO operation or calculation.
I hope now you understand why it's the MOST important thing! Unless you specifically know what your thread is doing, then there is no safe way to automatically cancel it.
P.S.
One thing to remember is that if you don't want hanging threads then for each one of them you can set the Thread.IsBackground flag to true and they will automatically be closed when your application exits.
Your worker threads need a way to check with your main thread to see if they should keep going. One way is to share a static volatile bool that's set by your UI and periodically checked by the worker threads.
My preference is to create your own threads that run instances of a worker class that periodically invoke a callback method provided by your main thread. This callback returns a value that tells the worker to continue, pause, or stop.
Avoid the temptation to use Thread.Abort() to kill worker threads: Manipulating a thread from a different thread.

Difference between Abort and Interrupt in Threads in .NET

What is the difference between Thraed.Abort() and Thread.Interrupt(). How can I call them in a Thread Safe Manner.It would be helpful,if simple example is provided.
First of all, neither of these are good thread synchronization constructs.
First, Thread.Abort says "I don't care what you're doing, just stop doing it, and leave everything as it is right now". It's basically the programming way of saying "Hey, beat it". If your thread is having files open, those files will be left open until garbage collection gets around to finalizing your objects.
Thread.Abort should only ever be used, and even then probably not, in the case when the app domain that the thread is running inside is being torn down, preferably only when the process is being terminated.
Secondly, Thread.Interrupt is a rather strange beast. It basically says "I don't care what you're waiting for, stop waiting for it". The strange thing here is that if the thread isn't currently waiting for anything, it's instead "I don't care what you're going to wait for next, but when you do, stop waiting for it immediately".
Both of these are signs that you're imposing your will on a thread that wasn't designed to be told such things.
To abort a thread properly, the thread should periodically check some kind of flag, be it a simple volatile Boolean variable, or an event object. If the flag says "You should now terminate", the thread should terminate itself by returning from the methods in an orderly fashion.
To properly wake a thread, a thread should, in places where it has to wait for synchronization objects, include a "please stop waiting" object that it also waits on. So basically it would for either the object it needs becomes signaled, or the "please stop waiting" object becomes signaled, determine which one that did, and do the right thing.
So instead of Thread.Abort and Thread.Interrupt, you should write your threads using normal synchronization objects, like events, mutexes, semaphores, etc.
For the same reason, Thread.Suspend and Thread.Resume should be left alone, and they have also been obsoleted in the later versions of .NET.
Unless you're calling Abort or Interrupt on the currently executing thread (as ASP.NET does to terminate a request abruptly, for example) you basically can't call them in a thread-safe manner.
Use a WaitHandle or Monitor.Wait/Pulse to wait in a wakeable way. You should only abort other threads if you're tearing down the application, basically - as otherwise you can end up in an unknown state.
See my article on graceful thread termination for an example of how to do this nicely.
Thread.Abort() raises a ThreadAbortException on the target thread. It's intent to generally to force the thread to terminate. It is not a recommended practice for stopping a thread's processing.
Thread.Interrupt() interrupts a thread that is in WaitSleepJoin state - essentially blocking on a resource like a WaitHandle. This allows the caller to unblock the thread.
Neither is really "thread-safe" - in the sense that they are specifically intended to affect the behavior of threads in a way that is hard to predict.
It's generally recommended to use synchronization objects (like WaitHandles or Semaphores) to allows threads to safely synchronize with one another.
The difference between Abort and Interrupt is that while they will both throw an exception (ThreadAbortException and ThreadInterruptException), calling Abort will rethrow the exception at the end of the catch block and will make sure to end your running thread.

How to abort threads created with ThreadPool.QueueUserWorkItem

is there a way to abort threads created with QueueUserWorkItem?
Or maybe I don't need to? What happens if the main application exits? Are all thread created from it aborted automatically?
You don't need to abort them. When your application exits, .NET will kill any threads with IsBackground = true. The .NET threadpool has all its threads set to IsBackground = true, so you don't have to worry about it.
Now if you're creating threads by newing up the Thread class, then you'll either need to abort them or set their IsBackground property to true.
However, if you are using unmanaged
resources in those threads, you may
end up in a lot of trouble.
That would rather depend how you were using them - if these unmanaged resources were properly wrapped then they'd be dealt with by their wrapper finalization regardless of the mechanism used to kill threads which had referenced them. And unmanaged resources are freed up by the OS when an app exits anyway.
There is a general feeling that (Windows) applications spend much too much time trying to clean-up on app shutdown - often involving paging-in huge amounts of memory just so that it can be discarded again (or paging-in code which runs around freeing unmangaged objects which the OS would deal with anyway).
The threadpool uses background threads. Hence, they will all be closed automatically when the application exits.
If you want to abort a thread yourself, you'll have to either manage the thread yourself (so you can call Thread.Abort() on the thread object) or you will have to set up some form of notification mechanism which will let you tell the thread that it should abort itself.
Yes, they will. However, if you are using unmanaged resources in those threads, you may end up in a lot of trouble.
yeah, they are background, but f.ex if you have application where you use ThreadPool for some kinda multiple downloading or stuff, and you want to stop them, how do you stop ? my suggestion would be:
exit thread asap, f.ex
bool stop = false;
void doDownloadWork(object s)
{
if (!stop)
{
DownloadLink((String)s, location);
}
}
and if you set stop = true, second (currently in queue) threads automatically exit, after queue threads finishes it process.
According to Lukas Ĺ alkauskas' answer.
But you should use:
volatile bool stop = false;
to tell the compiler this variable is used by several threads.

Categories

Resources