all threads : take a break!

  • Thread starter Thread starter Rainer Queck
  • Start date Start date
R

Rainer Queck

Hello NG,

is there a good, easy and safe way to:
- put all threads into a 'wait until I tell you to continue'
- get feed back that all threads are now waiting
< I now want to do some major data update >
- tell all threads to continue with work

Background: I am working on a multithreaded application. It is necessary to
swicht to different 'taskDataSets'. This swiching would influence all my
subthreads in one or the other way. Therefore I would like to 'globaly
synchronize' this taskswitching.

Regards
Rainer Queck
 
Hello NG,

is there a good, easy and safe way to:
- put all threads into a 'wait until I tell you to continue'
- get feed back that all threads are now waiting
< I now want to do some major data update >
- tell all threads to continue with work

Sure. Do it the same way anyone else would:

* create an object instance for use with the lock() statement
* protect code that shares data with other threads with the
lock() statement, including the thread that will do the
"major data update"

In the simplest case, you'd simply enter the lock() statement at regular
intervals during the processing. Eventually the main update thread would
be granted ownership of the lock, at which time it could be assured that
all of the other threads have reached a convenient stopping point and are
waiting for the update to finish.

Assuming the working threads don't conflict with each other, you would
probably want to have a different locking object for each thread. Then
you can use Monitor.TryEnter() from the main update thread to try to
acquire each of the working threads' locks; once it's finally gotten all
of the locks, it can safely perform whatever update you need it to.

You aren't very specific about your design, but if you can design things
so that the main update performs whatever update it needs to independently
from the working threads, and then can individually apply those updates to
each thread, that would avoid having all of the worker threads all waiting
at the same time. Given the assumption that the worker threads don't need
synchronization between each other, only with the main update thread,
there should be no problem implementing a solution this way.

If you need to put some larger block of code, one that won't exit the
lock() statement in any sort of timely fashion, into the lock() statement
but still want the working threads to be responsive in their sharing of
the lock, there are other more complicated techniques you can use. The
Monitor class, for example, provides different methods that allow a lock
to be released and acquired intermittently, as well as providing for a
"wait queue" where threads can be placed until some other thread signals
that there's no need to wait anymore.

As in the more basic solution, depending on how the threads depend on each
other, you could either assign a specific locking object to each thread,
or have the threads cooperate with each other as well as the main updating
thread. In some cases, it may be useful to have a volatile flag or some
kind of synchronization object for use for signaling between the threads.
Without knowing more about the problem, it's hard to say.

But it would be simplest if you could simply protect a small section of
code with the lock() statement, one that the working thread doesn't stay
executing inside for any single long length of time. And simpler is
usually better for multithreaded code. :)

Pete
 
[...]
In the simplest case, you'd simply enter the lock() statement at regular
intervals during the processing. Eventually the main update thread
would be granted ownership of the lock, at which time it could be
assured that all of the other threads have reached a convenient stopping
point and are waiting for the update to finish.

Re-reading this, I realize some clarification may be in order. Sorry...I
should have proof-read more carefully.

The above statement is accurate, but ambiguous. It's not literally true
that outside of the lock() statement, a worker thread can necessarily be
said to be "waiting". The point is that the lock() statement should be
used to protect all of the code that has a dependency on any other thread.

So, once the main update thread gets the lock, while it can't know for
sure that the other threads are sitting at their respective lock()
statements waiting, it _can_ know for sure that the other threads aren't
trying to do anything that might conflict with the main update thread's
work. This is because one would write the code specifically so that any
code outside of the lock() statement is safe to execute regardless of the
state of any other thread (in other words, it's not something that the
lock() statement automatically guarantees, but rather something that
naturally comes out of using the lock() statement correctly).

There are more complex ways to synchronize threads in which the other
threads _can_ be known to specifically be waiting rather than doing other
work, and I did describe the basics of that as well in my post. Hopefully
the post as a whole made all of this clear, but if not I hope that the
above clarifies things sufficiently. Sorry for any confusion I might have
caused.

Pete
 
is there a good, easy and safe way to:
- put all threads into a 'wait until I tell you to continue'

Yes, don't use assynchronous processes that have to be synchronized.

Cor
 
Hi Cor,

when you bring your car to a garage, telling them that you have some
difficulties with it, do they anwswer you " probably you should walk!" ?

Regards
Rainer
 
Hello Peter,

thanks for your thoughts.
Still that is not really what I am looking for. I was hoping for kind of a
"gate" where every body has to wait and where the "gate keeper" knows who is
waiting.
Once every body has arrivide, he would tell the boss (the one who as to do
the major data update) "ok we can start.....

Well, it looks like there is no system object (gate/gate keeper).

My current idea now is to implement a Event, to which all the threads have
to provide a event handler.
Then I fire the event which will set a "SyncFlag" . The thread loop then
would look like :
while(!terminated)
{
// wait for a autoresetevent
event.WaitOne();
if (SyncFlag)
{
... set property syncFlag ack
continue;
}
clear property syncFlag ack
do normal work
}

This way I can wait till all threads have their syncFlagAck set, do the data
update and then with a other event reset the SyncFlag....

I will rethink this a while, but currently this seems to be a way to get
what I want.

Regards
Rainer
 
when you bring your car to a garage, telling them that you have some
difficulties with it, do they anwswer you " probably you should walk!" ?
No the tell to buy a new car because they cannot repair "some difficulties"

If you tell that you want to go forward while the handle is set to backwards
they advice you not to do that.

(However with a client like you they maybe try to set the gearbox in a
different possition and write a big bill after that you signed a contract
that all problems are for you).

Cor
 
Back
Top