Click to See Complete Forum and Search --> : Multithreading


ktxn
April 27th, 2011, 12:41 PM
Hello,

I have a question and hope to get some helps or approaches from here.

My program has two child threads, thread1 and thread2 spawned from the main thread. when a button from the main thread is clicked, it checks user's selections on three check boxes. The checks can be in any combination, but they always be executed in sequence.

Thread1 is in charge of running three heavy calculations and thread2 is in charge of displaying results immediately after each calculation to the GUI. I have both threads created in main in the suspended states. When the button is clicked, thread1 starts doing his jobs. Once thread1 finishes his first job, it resumes thread2 to update the results to the screen. In the mean while, thread2 continues to do his second job.

The question I have is how do I put thread2 to pause until thread1 finishes his second job, then thread2 can update the results to screen, then continue one in this fashion. I do not want to use busy wait loop, because it will eat up lots of cpu time. What is the best approach here in this case?

Moreover, once thread1 finishes all his tasks, user can input different parameters and restart the calculation again with different selections.

VictorN
April 27th, 2011, 01:33 PM
Have a look at
Using Worker Threads (http://www.flounder.com/workerthreads.htm)

Arjay
April 30th, 2011, 03:14 PM
Hello,

I have a question and hope to get some helps or approaches from here.

My program has two child threads, thread1 and thread2 spawned from the main thread. when a button from the main thread is clicked, it checks user's selections on three check boxes. The checks can be in any combination, but they always be executed in sequence.

Thread1 is in charge of running three heavy calculations and thread2 is in charge of displaying results immediately after each calculation to the GUI. I have both threads created in main in the suspended states. When the button is clicked, thread1 starts doing his jobs. Once thread1 finishes his first job, it resumes thread2 to update the results to the screen. In the mean while, thread2 continues to do his second job.

The question I have is how do I put thread2 to pause until thread1 finishes his second job, then thread2 can update the results to screen, then continue one in this fashion. I do not want to use busy wait loop, because it will eat up lots of cpu time. What is the best approach here in this case?

Moreover, once thread1 finishes all his tasks, user can input different parameters and restart the calculation again with different selections.Create an event and wait on the event in thread2. When thread1 finishes its work, set the event.

ktxn
May 2nd, 2011, 05:38 PM
I have used Event objects to alternatively lock/unlock threads. Child thread handles the calculation while main thread handles the GUI update. The way I did was: I have 2 events created in main. When the program runs, and the STart button is pressed. STart handler function opens two events, creates a child thread and set event to the Event1. ThreadFunc() is a thread function that runs from child thread. STart() also calls Output() to update GUI right after the call to create the child thread.

ThreadFunc() has a loop. Inside the loop, WaitForSingleObject() is called at first to check for Event1.
It then does some calculation, saves the results to an array, resets Event1 and then sets Event2. Output() works similar to ThreadFunc(). It reads the data from the array generated from the child thread, reset Event2 and then set Event1.

This code works, but the GUI is unresponsive. I used FLTK tool kit for the GUI. If any of you use FLTK please give some advice, or you think there is a better approach then using Event objects, please give me some helps.

Thanks,

Igor Vartanov
May 4th, 2011, 01:06 AM
Frankly, all the scheme seems overcomplicated. As for me, the only one worker thread is needed - thread1. And I hardly can see a reason for having thread2, as typically main GUI thread does this kind of things alright, of course in case all the GUI data is already cooked by worker thread.

So, this is how I would go with all this. There is some global memory containing worker thread configuration parameters along with the data container needed for output results. The memory access is synchronized by critical section. The worker thread starts normal way (there's no need to have it suspended) and starts to wait on "GetToWork" event indefinitely. The main GUI thread in button click handler reads the check boxes and fills the worker configuration data. After that it signals GetToWork and returns. This way GUI thread remains unblocked. Worker thread after waking up on GetToWork starts doing its jobs sequentially phase by phase, and on finishing every phase it sends* a dedicated window message to GUI window reporting particular phase data got ready. GUI thread renders the data (I hope much faster than the other data get ready, otherwise some anti-jamming mechanism has to be introduced**). This happens until worker thread completes the job. After that it gets to wait on GetToWork event until next job coming.

I think most of the multi-threaded GUI apps operate this way.



* Should be posts.

** In fact, window message queue already is a sort of anti-jamming mechanism, as all the messages get processed in a row but not simultaneously. And therefore, the worker thread just should use PostMessage for notification purpose and don't try to access the already processed GUI data.

MikeAThon
May 4th, 2011, 08:38 PM
I largely agree with Igor, except for one very important clarification (which I think he intended, but I'm sure he will tell us):... Worker thread after waking up on GetToWork starts doing its jobs sequentially phase by phase, and on finishing every phase it sends a dedicated window message to GUI window reporting particular phase data got ready. ...
The worker thread should post the message, not send it. In other words, the worker thread should use PostMessage to post the message, and not SendMessage to send the message.

The reason is that SendMessage will require the worker thread to wait for a response from the GUI thread before the worker can continue execution, whereas PostMessage does not. In the best case, this will cause significant delays, since the GUI thread cannot respond until there's a thread context switch, and the worker thread connot recognize the response until there's a thread context swithc back to the worker (at least in a single core machine that's true). In the worst case, there can be a deadlock, if (for example) the GUI thread decides that it needs something from the worker thread before it can respond to the SendMessage. Such a deadlock would occur even in a multi-core machine.

Mike

Igor Vartanov
May 5th, 2011, 12:10 AM
Mike, you're right, that 'send' was just to give an idea. In the same post below you can find my mentioning of PostMessage. :)

ktxn
May 9th, 2011, 02:10 PM
I have coded like this:

main thread updates the GUI, child thread performs calculation. Main thread has a loop checking if each data point is available for output using while loop as

for (i.. 30000)
{
lock
while(data[i] != -1) Sleep(10);
output
unlock
}

but the overall running time of the worker thread runs on 1 core takes 3 times more than without using multithread, and even running it on a dual core. Any suggestion/explaination is really appreciated.

Thanks

VictorN
May 9th, 2011, 02:17 PM
Remove all the "locks" and Sleep() from the GUI thread! :cool:

ktxn
May 9th, 2011, 02:48 PM
I removed all locks and sleep, it still takes about the same time. What is the difference of running multithreaded program on single core vs on dual/multiple cores?

Thanks

VictorN
May 9th, 2011, 02:55 PM
...
but the overall running time of the worker thread runs on 1 core takes 3 times more than without using multithread, ...Sounds like a bad design or/and bad implementation... :rolleyes:

ktxn
May 9th, 2011, 03:09 PM
How to use postmessage() and how to make it more efficient? Will postmessage() give a better implementation in term of execution time.? Thanks for any suggestion.

VictorN
May 9th, 2011, 03:14 PM
I already gave you a link in the post#2. :cool:

MikeAThon
May 9th, 2011, 03:27 PM
for (i.. 30000)
{
lock
while(data[i] != -1) Sleep(10);
output
unlock
}

but the overall running time of the worker thread runs on 1 core takes 3 times more than without using multithread, and even running it on a dual core. Any suggestion/explaination is really appreciated.
Remove all of this code, which polls for results in the main GUI thread (very bad). Your main GUI thread should react to the messages that Igor mentioned, which are posted from the worker thread. Something like this:
// in worker thread
// when something is finished in the worker, which
// warrants an update to the gui
::PostMessage(hWndGuiThread, MYSPECIALMESSAGE, (WPARAM) result1, (LPARAM) result2);

// ... where result1 and result2 are coded message contents from the worker thread, if needed


// in main GUI thread
LRESULT OnMySpecialMessage( WPARAM wParam, LPARAM lParam)
{
// decode wParam and lParam
output
return 0L;
}
This architecture will avoid polling, and will probably exhibit increased performance and decreased times. If not, then the issue might be related to "false sharing".

Mike

Igor Vartanov
May 10th, 2011, 03:39 AM
Main thread has a loop checking if each data point is available for output using while loop as
Sounds like a bad design...Normally (except really trivial cases) multithreaded architecture builds on top of message/event notification mechanism. This way data processing occurs only when it's really needed. Locking mechanisms are acceptable in GUI, but should be implemented most effective way having in mind minimal possible GUI blocking. The least blocking schema is: worker thread fills the data block, signals data ready and never touches it anymore.

What is the difference of running multithreaded program on single core vs on dual/multiple cores?On a single core hardware Windows kernel does preemptive execution when each thread one by one is given with a time slice, during which only one thread possesses the CPU core. On a multicore system threads appear distributed among the cores available at a time, and this way it may happen that few threads of the same app get executed simultaneously.

ktxn
May 10th, 2011, 08:43 PM
Is it appropriate to have a program that uses a core to do an intensive calculation and another core to output the results simultaneously on a dualcore machine? can i use MPI library to do this task?

I tried multithreading on a dualcore machine with the same idea that one thread does the calculation while the other thread displaying results, but the two cores do not process simultaneously.

Thanks,

Igor Vartanov
May 11th, 2011, 08:35 AM
I tried multithreading on a dualcore machine with the same idea that one thread does the calculation while the other thread displaying results, but the two cores do not process simultaneously.And how did you find that out?

ktxn
May 11th, 2011, 12:36 PM
I look at the performance tab in task manager. I also timed it, the running time on dualcore machine does not improve a lot compared to the one core machine.

MikeAThon
May 11th, 2011, 12:57 PM
..., but the two cores do not process simultaneously.
Why would you expect them to? According to your description, the first thread does intensive calculations and the second thread displays results. Assuming that the two thread are on separate cores (probably reasonable), then the the second thread has nothing to do until the first thread sends it results for display. This matches your observed behavior.

In your scenario, mutithreading provides the advantage that the GUI stays alive while the intensive calculation proceeds. But in this scenario, multithreading does not provide a time/speed advantage.

To obtain a time/speed advantage, the intensive calculation must itself be multithreaded. That generally can be hard to do, unless the intensive calculation has some nice parallel properties.

Mike

samualrich123
June 29th, 2011, 02:55 PM
In programs there are threads. Threads are doing process. There are many thread with performing different processes. At a time we can do many process with the help of multi threading. Threads have many states like start,intiate,stop,turminate.