I'm trying to obtain a good understanding of multi-threading in C# and I'm a bit confused about the applicability of the Thread.Join method. Microsoft says that it "Blocks the calling thread until a thread terminates." Two questions:
Given the following example, which thread is actually blocked while the other is working toward termination?
Doesn't the fact that one thread is blocked while the other is executing toward termination actually defeat the purpose of multi-threads? (So I assume you only want to join in certain situations. What might those be?)
static int Main()
{
Alpha oAlpha = new Alpha();
Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));
oThread.Start();
oThread.Join();
}
I should also note that it is wholly possible that I'm not doing something correct here.
Main is blocked until oThread Completes.
The idea is that you can terminate on thread cleanly and wait for it to clean up after itself, rather than killing the thread sloppily.
It is also useful for starting a batch of three or four independent processes, and then continuing once ALL of them complete.
the thread that is running the Main() method blocks.
Threads often need to synchronize, for instance, if you didn't want your main method to exit until all the work was done. In your example, there's no benefit, but you could insert useful work in between the Start() and Join() calls. This is particularly useful if you spin off multiple threads and then join them all.
Related
Basically I'm working on this beat detection algorithm, the strange thing i am encountering right now is that when i split the work load on to another thread. So now i have one main thread and another worker thread. My worker thread somehow is always working faster than the main thread. It seems strange because what i have learned is that the main thread should theoretically always be faster because it is not taking time to initialise the thread. However what i get is even i pass a extra 1024 samples to the worker thread( they are both working with around 30 million samples currently) it is still faster than the main thread. Is it because i have applications running on my main thread? I'm really confused right now. here is the code
UnityEngine.Debug.Log ("T800 Start");
Step3 s1= new Step3();
Step3WOMT s2= new Step3WOMT();
System.Object tempObj= samples2 as System.Object;
float[] tempArray = new float[eS.Length/ 2];
System.Threading.ParameterizedThreadStart parameterizedts = new System.Threading.ParameterizedThreadStart(s1.DoStep3);
System.Threading.Thread T1 = new System.Threading.Thread(parameterizedts);
T1.Start (tempObj);
s2.DoStep3(samples1);
UnityEngine.Debug.Log ("s2");
//UnityEngine.Debug.Log (stopwatch.ElapsedMilliseconds);
T1.Join();
Don't worry I'm only using c# features in the multithread so I believe it should be fine. What i am really confused about is that if i comment out the T1.join(); line the whole thing somehow go even slower. Im genuinely confused right now as there seems no reasonable answer to this question.
T1.join() does all the magic. It allow main thread to wait till all the worker threads are complete. Is that necessary ? depends on ur application. it is expected for a main thread to wait for the end of execution of its worker threads.
Your system must have multiple cores.
It's possible that Thread.Start can return not immediately after the thread is initialized. Anyway you should use ThreadPool.EnqueueUserWorkItem and ManualResetEvent to wait instead of join.
To see real results your samples count must be big enough so that thread initialization time is minimal compared to the execution time of your code. ThreadPool often doesn't have to initialize a new thread but it still takes some time to launch your code. I think you should not use multithreading for tasks which takes <~50ms.
If you compare the execution time for big samples count (takes few seconds) you'll see that there is no difference in the performance of the main thread and the background one (unless the main thread have higher priority).
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.)
I heard there is limitation when using waitall on multiple threads (# of threads to wait?). Can anyone give details?
I think the restriction you are referring to is not on the number of threads; it is on the number of handles being waited on. From the MSDN page for WaitHandle.WaitAll(WaitHandle[]):
On some implementations, if more than
64 handles are passed, a
NotSupportedException is thrown.
On the rare occasion that this issue has cropped, I have normally worked around it with:
WaitHandle[] handles = ...
foreach(var waitHandle in handles)
waitHandle.WaitOne();
For completeness, the other restrictions appear to be:
If the array contains duplicates, the
call fails with a
DuplicateWaitObjectException.
The WaitAll method is not supported on
threads that have STAThreadAttribute.
Are you thinking of the STA (single-threaded apartment) limitation of a winform app?
If so, I handle this by simply checking if the 'work queue' is empty after each thread has done it's processing, and calling .WaitOne() on a single ManualResetEvent object that the main thread owns instead of using .WaitAll() at all.
Like this:
moSolverEvent = new ManualResetEvent(false);
ProcessResult(new SolverWorkInProgress());
//Wait here until the last background thread reports in
moSolverEvent.WaitOne();
And then the worker threads are doing this:
if (mhSolverWorkQueue.Count == 0) moSolverEvent.Set();
It works spectacularly well, and avoids any issues with WaitAll(), even in a WinForms app. After all, you're not really waiting for the threads to be done... you're waiting for the WORK to be done. :-)
Just be sure to do the appropriate locking on each of these objects so your threads don't step all over each other.
If I have Thread A which is the main Application Thread and a secondary Thread. How can I check if a function is being called within Thread B?
Basically I am trying to implement the following code snippit:
public void ensureRunningOnCorrectThread()
{
if( function is being called within ThreadB )
{
performIO()
}
else
{
// call performIO so that it is called (invoked?) on ThreadB
}
}
Is there a way to perform this functionality within C# or is there a better way of looking at the problem?
EDIT 1
I have noticed the following within the MSDN documentation, although Im a dit dubious as to whether or not its a good thing to be doing! :
// if function is being called within ThreadB
if( System.Threading.Thread.CurrentThread.Equals(ThreadB) )
{
}
EDIT 2
I realise that Im looking at this problem in the wrong way (thanks to the answers below who helped me see this) all I care about is that the IO does not happen on ThreadA. This means that it could happen on ThreadB or indeed anyother Thread e.g. a BackgroundWorker. I have decided that creating a new BackgroundWorker within the else portion of the above f statement ensures that the IO is performed in a non-blocking fashion. Im not entirely sure that this is the best solution to my problem, however it appears to work!
Here's one way to do it:
if (System.Threading.Thread.CurrentThread.ManagedThreadId == ThreadB.ManagedThreadId)
...
I don't know enough about .NET's Thread class implementation to know if the comparison above is equivalent to Equals() or not, but in absence of this knowledge, comparing the IDs is a safe bet.
There may be a better (where better = easier, faster, etc.) way to accomplish what you're trying to do, depending on a few things like:
what kind of app (ASP.NET, WinForms, console, etc.) are you building?
why do you want to enforce I/O on only one thread?
what kind of I/O is this? (e.g. writes to one file? network I/O constrained to one socket? etc.)
what are your performance constraints relative to cost of locking, number of concurrent worker threads, etc?
whether the "else" clause in your code needs to be blocking, fire-and-forget, or something more sophisticated
how you want to deal with timeouts, deadlocks, etc.
Adding this info to your question would be helpful, although if yours is a WinForms app and you're talking about user-facing GUI I/O, you can skip the other questions since the scenario is obvious.
Keep in mind that // call performIO so that it is called (invoked?) on ThreadB implementation will vary depending on whether this is WinForms, ASP.NET, console, etc.
If WinForms, check out this CodeProject post for a cool way to handle it. Also see MSDN for how this is usually handled using InvokeRequired.
If Console or generalized server app (no GUI), you'll need to figure out how to let the main thread know that it has work waiting-- and you may want to consider an alternate implementation which has a I/O worker thread or thread pool which just sits around executing queued I/O requests that you queue to it. Or you might want to consider synchronizing your I/O requests (easier) instead of marshalling calls over to one thread (harder).
If ASP.NET, you're probably implementing this in the wrong way. It's usually more effective to use ASP.NET async pages and/or to (per above) synchronize snchronizing to your I/O using lock{} or another synchronization method.
What you are trying to do is the opposite of what the InvokeRequired property of a windows form control does, so if it's a window form application, you could just use the property of your main form:
if (InvokeRequired) {
// running in a separate thread
} else {
// running in the main thread, so needs to send the task to the worker thread
}
The else part of your snippet, Invoking PerformIO on ThreadB is only going to work when ThreadB is the Main thread running a Messageloop.
So maybe you should rethink what you are doing here, it is not a normal construction.
Does your secondary thread do anything else besides the performIO() function? If not, then an easy way to do this is to use a System.Threading.ManualResetEvent. Have the secondary thread sit in a while loop waiting for the event to be set. When the event is signaled, the secondary thread can perform the I/O processing. To signal the event, have the main thread call the Set() method of the event object.
using System.Threading;
static void Main(string[] args)
{
ManualResetEvent processEvent = new ManualResetEvent(false);
Thread thread = new Thread(delegate() {
while (processEvent.WaitOne()) {
performIO();
processEvent.Reset(); // reset for next pass...
}
});
thread.Name = "I/O Processing Thread"; // name the thread
thread.Start();
// Do GUI stuff...
// When time to perform the IO processing, signal the event.
processEvent.Set();
}
Also, as an aside, get into the habit of naming any System.Threading.Thread objects as they are created. When you create the secondary thread, set the thread name via the Name property. This will help you when looking at the Threads window in Debug sessions, and it also allows you to print the thread name to the console or the Output window if the thread identity is ever in doubt.
Alright...I've given the site a fair search and have read over many posts about this topic. I found this question: Code for a simple thread pool in C# especially helpful.
However, as it always seems, what I need varies slightly.
I have looked over the MSDN example and adapted it to my needs somewhat. The example I refer to is here: http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80,printer).aspx
My issue is this. I have a fairly simple set of code that loads a web page via the HttpWebRequest and WebResponse classes and reads the results via a Stream. I fire off this method in a thread as it will need to executed many times. The method itself is pretty short, but the number of times it needs to be fired (with varied data for each time) varies. It can be anywhere from 1 to 200.
Everything I've read seems to indicate the ThreadPool class being the prime candidate. Here is what things get tricky. I might need to fire off this thing say 100 times, but I can only have 3 threads at most running (for this particular task).
I've tried setting the MaxThreads on the ThreadPool via:
ThreadPool.SetMaxThreads(3, 3);
I'm not entirely convinced this approach is working. Furthermore, I don't want to clobber other web sites or programs running on the system this will be running on. So, by limiting the # of threads on the ThreadPool, can I be certain that this pertains to my code and my threads only?
The MSDN example uses the event drive approach and calls WaitHandle.WaitAll(doneEvents); which is how I'm doing this.
So the heart of my question is, how does one ensure or specify a maximum number of threads that can be run for their code, but have the code keep running more threads as the previous ones finish up until some arbitrary point? Am I tackling this the right way?
Sincerely,
Jason
Okay, I've added a semaphore approach and completely removed the ThreadPool code. It seems simple enough. I got my info from: http://www.albahari.com/threading/part2.aspx
It's this example that showed me how:
[text below here is a copy/paste from the site]
A Semaphore with a capacity of one is similar to a Mutex or lock, except that the Semaphore has no "owner" – it's thread-agnostic. Any thread can call Release on a Semaphore, while with Mutex and lock, only the thread that obtained the resource can release it.
In this following example, ten threads execute a loop with a Sleep statement in the middle. A Semaphore ensures that not more than three threads can execute that Sleep statement at once:
class SemaphoreTest
{
static Semaphore s = new Semaphore(3, 3); // Available=3; Capacity=3
static void Main()
{
for (int i = 0; i < 10; i++)
new Thread(Go).Start();
}
static void Go()
{
while (true)
{
s.WaitOne();
Thread.Sleep(100); // Only 3 threads can get here at once
s.Release();
}
}
}
Note: if you are limiting this to "3" just so you don't overwhelm the machine running your app, I'd make sure this is a problem first. The threadpool is supposed to manage this for you. On the other hand, if you don't want to overwhelm some other resource, then read on!
You can't manage the size of the threadpool (or really much of anything about it).
In this case, I'd use a semaphore to manage access to your resource. In your case, your resource is running the web scrape, or calculating some report, etc.
To do this, in your static class, create a semaphore object:
System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);
Then, in each thread, you do this:
System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);
try
{
// wait your turn (decrement)
S.WaitOne();
// do your thing
}
finally {
// release so others can go (increment)
S.Release();
}
Each thread will block on the S.WaitOne() until it is given the signal to proceed. Once S has been decremented 3 times, all threads will block until one of them increments the counter.
This solution isn't perfect.
If you want something a little cleaner, and more efficient, I'd recommend going with a BlockingQueue approach wherein you enqueue the work you want performed into a global Blocking Queue object.
Meanwhile, you have three threads (which you created--not in the threadpool), popping work out of the queue to perform. This isn't that tricky to setup and is very fast and simple.
Examples:
Best threading queue example / best practice
Best method to get objects from a BlockingQueue in a concurrent program?
It's a static class like any other, which means that anything you do with it affects every other thread in the current process. It doesn't affect other processes.
I consider this one of the larger design flaws in .NET, however. Who came up with the brilliant idea of making the thread pool static? As your example shows, we often want a thread pool dedicated to our task, without having it interfere with unrelated tasks elsewhere in the system.