Waiting thread count and working thread count on Semaphore - c#

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.

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.

Why is it bad to pause/abort threads?

My model of how threads work is that some ThreadManager gives each thread a turn. When it's a thread's turn, it gets to execute a few lines of code.
To pause a thread, couldn't one just have the ThreadManager (momentarily) stop allowing that thread to have a turn?
To abort a thread, couldn't the ThreadManager just never give that thread another turn?
What's the problem?
Quote from MSDN about pausing threads:
You have no way of knowing what code a
thread is executing when you suspend
it. If you suspend a thread while it
holds locks during a security
permission evaluation, other threads
in the AppDomain might be blocked. If
you suspend a thread while it is
executing a class constructor, other
threads in the AppDomain that attempt
to use that class are blocked.
Deadlocks can occur very easily.
Aborted thread can lead to unpredicted circumstances. There is a good article about this: http://www.bluebytesoftware.com/blog/2009/03/13/ManagedCodeAndAsynchronousExceptionHardening.aspx
I agree with Alex, but to elaborate further, if you need to "pause" a thread, it will probably be better to look at some sort of locking mechanism like Semaphores, Mutexes, or one of the many other ones available.
But, without knowing your code, Windows is a preemptive multitasking environment. Usually this is not needed, just let your threads run and the underlying OS and scheduler will make sure all your tasks get a fair turn.

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.

.NET Thread Pool - Unresponsive WinForms UI

Scenario
I have a Windows Forms Application. Inside the main form there is a loop that iterates around 3000 times, Creating a new instance of a class on a new thread to perform some calculations. Bearing in mind that this setup uses a Thread Pool, the UI does stay responsive when there are only around 100 iterations of this loop (100 Assets to process). But as soon as this number begins to increase heavily, the UI locks up into eggtimer mode and the thus the log that is writing out to the listbox on the form becomes unreadable.
Question
Am I right in thinking that the best way around this is to use a Background Worker?
And is the UI locking up because even though I'm using lots of different threads (for speed), the UI itself is not on its own separate thread?
Suggested Implementations greatly appreciated.
EDIT!!
So lets say that instead of just firing off and queuing up 3000 assets to process, I decide to do them in batches of 100. How would I go about doing this efficiently? I made an attempt earlier at adding "Thread.Sleep(5000);" after every batch of 100 were fired off, but the whole thing seemed to crap out....
If you are creating 3000 separate threads, you are pushing a documented limitation of the ThreadPool class:
If an application is subject to bursts
of activity in which large numbers of
thread pool tasks are queued, use the
SetMinThreads method to increase the
minimum number of idle threads.
Otherwise, the built-in delay in
creating new idle threads could cause
a bottleneck.
See that MSDN topic for suggestions to configure the thread pool for your situation.
If your work is CPU intensive, having that many separate threads will cause more overhead than it's worth. However, if it's very IO intensive, having a large number of threads may help things somewhat.
.NET 4 introduces outstanding support for parallel programming. If that is an option for you, I suggest you have a look at that.
More threads does not equal top speed. In fact too many threads equals less speed. If your task is simply CPU related you should only be using as many threads as you have cores otherwise you're wasting resources.
With 3,000 iterations and your form thread attempting to create a thread each time what's probably happening is you are maxing out the thread pool and the form is hanging because it needs to wait for a prior thread to complete before it can allocate a new one.
Apparently ThreadPool doesn't work this way. I have never checked it with threads before so I am not sure. Another possibility is that the tasks begin flooding the UI thread with invocations at which point it will give up on the GUI.
It's difficult to tell without seeing code - but, based on what you're describing, there is one suspect.
You mentioned that you have this running on the ThreadPool now. Switching to a BackgroundWorker won't change anything, dramatically, since it also uses the ThreadPool to execute. (BackgroundWorker just simplifies the invoke calls...)
That being said, I suspect the problem is your notifications back to the UI thread for your ListBox. If you're invoking too frequently, your UI may become unresponsive while it tries to "catch up". This can happen if you're feeding too much status info back to the UI thread via Control.Invoke.
Otherwise, make sure that ALL of your work is being done on the ThreadPool, and you're not blocking on the UI thread, and it should work.
If every thread logs something to your ui, every written log line must invoke the main thread. Better to cache the log-output and update the gui only every 100 iterations or something like that.
Since I haven't seen your code so this is just a lot of conjecture with some highly hopefully educated guessing.
All a threadpool does is queue up your requests and then fire new threads off as others complete their work. Now 3000 threads doesn't sounds like a lot but if there's a ton of processing going on you could be destroying your CPU.
I'm not convinced a background worker would help out since you will end up re-creating a manager to handle all the pooling the threadpool gives you. I think more you issue is you've got too much data chunking going on. I think a good place to start would be to throttle the amount of threads you start and maintain. The threadpool manager easily allows you to do this. Find a balance that allows you to process data while still keeping the UI responsive.

Keep threads idle or kill them / restart them?

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.

Categories

Resources