Good practice for an approximation algorithm with start & stop features

  • Thread starter Thread starter Joannes Vermorel
  • Start date Start date
J

Joannes Vermorel

I am currently implementing a multithreaded application that performs some
scientific computations. To make thing simple, lets says it is "iterative
approximation algorithm with start&stop features".

For now the implementation looks like:

class MyAlgo {
Thread myThread;
bool isStopRequested;

public void StartComputation() {
isStopRequested = false;
myThread = new Thread(new ThreadStart(Iterating));
myThread.Start();
}

private void Iterating() {
while(!isStopRequested) { /* performs one iteration (improving an
approximation) */ }
}

public void StopComputation() {
isStopRequested = true;
myThread.Join();
}
}

I would like to know if such template is considered as a "good practice". I
would appreciate if anyone could provide feed-back and/or pointer to design
patterns related to such situations.

Thanks,
Joannes
 
Joannes Vermorel said:
I am currently implementing a multithreaded application that performs some
scientific computations. To make thing simple, lets says it is "iterative
approximation algorithm with start&stop features".

<snip>

Nearly there, but you should either make isStopRequested a volatile, or
put a lock round it, eg

object stopLock = new object();
bool isStopRequested=false;

bool IsStopRequested
{
get
{
lock (stopLock)
{
return isStopRequested;
}
}

set
{
lock (stopLock)
{
isStopRequested=value;
}
}
}
 
Joannes,

You could do this. You should place lock statements around access to
isStopRequested, as they could be accessed by multiple threads at the same
time.

You might get better performance by using the ThreadPool, assuming that
each iteration through the loop is short, you can have the threadpool run
multiple operations at the same time, and then at the end of each, they
would place the next item in the queue for the thread pool.

Hope this helps.
 
Joannes Vermorel said:
I am currently implementing a multithreaded application that performs some
scientific computations. To make thing simple, lets says it is "iterative
approximation algorithm with start&stop features".

For now the implementation looks like:

class MyAlgo {
Thread myThread;
bool isStopRequested;

public void StartComputation() {
isStopRequested = false;
myThread = new Thread(new ThreadStart(Iterating));
myThread.Start();
}

private void Iterating() {
while(!isStopRequested) { /* performs one iteration (improving an
approximation) */ }
}

public void StopComputation() {
isStopRequested = true;
myThread.Join();
}
}

I would like to know if such template is considered as a "good practice". I
would appreciate if anyone could provide feed-back and/or pointer to design
patterns related to such situations.

IMO it is safest to use an "event" and signal a thread termination request.
ManualResetEvent is good for this.

The loop (pseudo-loop):
while( iteration should continue )
{
if( (iterations % checkRate)==0 && shutdownRequest.waitOne(0,
false) )
break; // shutdownRequest signaled here, break out
// iteration ...
}

Setting the event signaled:
shutdownRequest.Set();

Resetting:
shutdownRequest.Reset();

You could argue that a bool uses less memory and is faster to check, but you
would need volatile for the variable and volatile is actually not entirely
safe to use in multi-threading. At least it is not safe in C or C++
(generally speaking), and I assume it isn't for C# either. In this case you
will probably get away with the volatile bool.
 
TT (Tom Tempelaere) <"TT \(Tom Tempelaere\)" <_N_0SPA|/
\|[email protected]|/\|APS0_N_> said:
IMO it is safest to use an "event" and signal a thread termination request.
Why?

You could argue that a bool uses less memory and is faster to check, but you
would need volatile for the variable and volatile is actually not entirely
safe to use in multi-threading. At least it is not safe in C or C++
(generally speaking), and I assume it isn't for C# either.

That's a false assumption. Using either a volatile bool or explicitly
locking on each check makes it thread-safe. The CLR has well-defined
memory access guarantees.
In this case you will probably get away with the volatile bool.

In most cases you could probably actually get away with a non-volatile
bool, but you're guaranteed to be able to get away with a volatile
bool.
 
Hi Jon

Actually I should have said, "in general it is better to use events to signal something in multi-threaded applications". Perhaps not in this very case, but the fact is that I never use primitive data types to signal anything. It is a decision I made and is in the line of what I think is the "path of least resistance". If at some point in time I notice that using events creates a bottleneck for a specific project or execution path, then I would consider using (volatile) bools. But my first bet is events to signal, nothing else. This is just a matter of style I guess

Another thing, which is not relevant to the original question, is that you cannot use the bool to wait on. Event classes in C# like ManualResetEvent derive from WaitHandle, so you can use the Wait functions

Tom

----- Jon Skeet [C# MVP] wrote: ----

TT (Tom Tempelaere) <"TT \(Tom Tempelaere\)" <_N_0SPA|
\|[email protected]|/\|APS0_N_>> wrote
IMO it is safest to use an "event" and signal a thread termination request
Why

You could argue that a bool uses less memory and is faster to check, but yo
would need volatile for the variable and volatile is actually not entirel
safe to use in multi-threading. At least it is not safe in C or C+
(generally speaking), and I assume it isn't for C# either.

That's a false assumption. Using either a volatile bool or explicitly
locking on each check makes it thread-safe. The CLR has well-defined
memory access guarantees
In this case you will probably get away with the volatile bool

In most cases you could probably actually get away with a non-volatile
bool, but you're guaranteed to be able to get away with a volatile
bool
 
TT (Tom Tempelaere) <"=?Utf-8?B?VFQgKFRvbSBUZW1wZWxhZXJlKQ==?=" <_N_
0SPA|/\|[email protected]|/\|APS0_N_> said:
Actually I should have said, "in general it is better to use events
to signal something in multi-threaded applications". Perhaps not in
this very case, but the fact is that I never use primitive data types
to signal anything. It is a decision I made and is in the line of
what I think is the "path of least resistance". If at some point in
time I notice that using events creates a bottleneck for a specific
project or execution path, then I would consider using
(volatile)bools. But my first bet is events to signal, nothing else.
This is just a matter of style I guess.

Another thing, which is not relevant to the original question, is
that you cannot use the bool to wait on. Event classes in C# like
ManualResetEvent derive from WaitHandle, so you can use the Wait
functions.

Indeed - and the important thing here is "not relevant". If a queue of
work items is required, I'd then still just use locks and Monitor.Wait,
personally - but it's the same principle as ManualResetEvent etc.

However, when no actual waiting is required, I don't see the point in
using anything other than a flag.
 
Jon

Consider the fact that you use a bool as a signal, and later on in the project you notice that you need to wait. Since events allow this by definition, you would not need to change anything when you use events

Events allow every operation that has to do with signaling. Bools don't. That is at least one thing that is on the path of least resistance, meaning that I don't have to change code (or mindset) if I notice I need waiting

Another issue, indeed less to the point, is that volatile is an ugly beast in C/C++ and that it is strongly advised everywhere not to use it for multi-threading purposes in C/C++. C# specifies the behaviour of volatile more precisely, and for this program it will work, but that doesn't make me use it at all. Volatile is something I would only use when there is absolutely no other choice (e.g. when having performance issues). Again, this is a matter of style. I think of my way as the better way, because I am using an object that models an event. Bool doesn't say anything. XXXEvent sais it all; we are dealing with an event which is used to signal something.

I don't mean to say that you should use an event where possible, I'm saying not to use volatile bool unless you have no other choice (and I'm guessing 99.99% of the times you do have other choices). Again, this is my personal view on things. I am not an expert in multi-threading apps, I just happen to be coding multi-threaded programs nowadays.

I understand why you would choose not to use events. Why the overhead? Then I think of something different: a programmer sees an event and knows he is dealing with an event (by looking at its type when defined). When the programmer sees a bool, he doesn't know it is an event, unless he reads the documentation and/or the use of that bool throughout the program

With kind regards
Tom

----- Jon Skeet [C# MVP] wrote: ----

TT (Tom Tempelaere) <"=?Utf-8?B?VFQgKFRvbSBUZW1wZWxhZXJlKQ==?=" <_N
0SPA|/\|[email protected]|/\|APS0_N_>> wrote
Actually I should have said, "in general it is better to use event
to signal something in multi-threaded applications". Perhaps not i
this very case, but the fact is that I never use primitive data type
to signal anything. It is a decision I made and is in the line o
what I think is the "path of least resistance". If at some point i
time I notice that using events creates a bottleneck for a specifi
project or execution path, then I would consider usin
(volatile)bools. But my first bet is events to signal, nothing else
This is just a matter of style I guess
that you cannot use the bool to wait on. Event classes in C# lik
ManualResetEvent derive from WaitHandle, so you can use the Wai
functions

Indeed - and the important thing here is "not relevant". If a queue of
work items is required, I'd then still just use locks and Monitor.Wait,
personally - but it's the same principle as ManualResetEvent etc

However, when no actual waiting is required, I don't see the point in
using anything other than a flag
 
TT (Tom Tempelaere) <"=?Utf-8?B?VFQgKFRvbSBUZW1wZWxhZXJlKQ==?=" <_N_
0SPA|/\|[email protected]|/\|APS0_N_> said:
Consider the fact that you use a bool as a signal, and later on in
the project you notice that you need to wait. Since events allow this
by definition, you would not need to change anything when you use
events.

Sure - but you've got more complicated code.
Events allow every operation that has to do with signaling. Bools
don't. That is at least one thing that is on the path of least
resistance, meaning that I don't have to change code (or mindset) if
I notice I need waiting.

But then, if you *don't* need waiting, you've ended up writing more
code (and harder to read code) for no reason.
Another issue, indeed less to the point, is that volatile is an ugly
beast in C/C++ and that it is strongly advised everywhere not to use
it for multi-threading purposes in C/C++. C# specifies the behaviour
of volatile more precisely, and for this program it will work, but
that doesn't make me use it at all.

I don't see why you're bringing C/C++ up again. We're talking about C#
- what is good or not good in different languages is entirely
irrelevant. Brining hang-ups or assumptions from one language to
another is a bad idea.
Volatile is something I would
only use when there is absolutely no other choice (e.g. when having
performance issues). Again, this is a matter of style. I think of
my way as the better way, because I am using an object that models an
event. Bool doesn't say anything. XXXEvent sais it all; we are dealing
with an event which is used to signal something.

To me, a bool which says "stopRunning" is a flag which is perfectly
readable - more so than an event, to be honest. Look at it in terms of
how the code reads - why should I be *waiting* on anything when all I
want to know is whether or not to stop running? Waiting on an event is
not a natural way of considering a simple condition - testing a boolean
is.
I don't mean to say that you should use an event where possible, I'm saying
not to use volatile bool unless you have no other choice (and I'm
guessing 99.99% of the times you do have other choices). Again, this
is my personal view on things. I am not an expert in multi-threading
apps, I just happen to be coding multi-threaded programs nowadays.

But your recommendation not to use volatile booleans is without merit,
and seems to be based on superstition coming from a C/C++ background.
There's no reason to particularly avoid volatiles, although as I've
said before (I think) I personally prefer using monitor locking, as it
then extends naturally to accessing to more than one variable at a
time.
I understand why you would choose not to use events. Why the
overhead? Then I think of something different: a programmer sees an
event and knows he is dealing with an event (by looking at its type
when defined). When the programmer sees a bool, he doesn't know it is
an event, unless he reads the documentation and/or the use of that
bool throughout the program.

The bool should, of course, be a well-documented property.
Alternatively, you could only set it from a public method, "Stop" or
suchlike - and then the actual implementation is *entirely* hidden from
the interface. If you wanted to use an event later on, you could do so
without changing the interface. Why expose an event at all if what
you're really wanting is a way of people saying, "I want you to stop
soon"?
 
TT (Tom Tempelaere) <"=?Utf-8?B?VFQgKFRvbSBUZW1wZWxhZXJlKQ==?=" <_N_
0SPA|/\|[email protected]|/\|APS0_N_> said:
What you say is true, and I agree with you. Perhaps I'm still
struggling too much with my c++ background. But I will have to take
extra care not to mix the C# volatile with volatile in C/C++ when I
have to do another project in C++. But that is part of the job I
guess. I have to constantly be aware of these issues, because I'm
dealing with different languages all the time. Another fact is that a
lot of C# coders have a C++ background, and it is worth mentioning
the difference of volatile in these languages because the languages look
similar. That's why I mentioned it.

Right. However, treating *anything* as the same between two languages
is a potential problem. That's why I rigorously try to stick with the
idioms, naming conventions etc of a new language - it helps me to think
in that language, rather than one which happens to look like it :)
I do (of course) hide any specifics of the event to the client, so
that is not an issue. Asking the thread to finish is just calling a
method, checking whether shutdown was requested is just another. Then
one can implement it like he wants.

The event stopRunning or the bool stopRunning would have the same
name. I agree that testing a boolean is more readable than waiting.
Right.

When you speak of locking, you mean that you would use a locking
object to access the boolean instead of making it volatile? Like:

Object lockObject = new Object();
bool stopRunning = false;

// signal:
lock( lockObject ) { stopRunning= true; }

// check signal
lock( lockObject ) { if(stopRunning) {...}}

Or did I get you wrong?

Nope, that's exactly it. I'd put the actual lock within the property,
but yes, that's the thing. The semantics of "lock" include a read
memory barrier when acquiring, and a write memory barrier when
releasing, so that you get volatile behaviour.
 
Hi Jon

I do not wish to reopen this discussion. But I was just browsing through IDesign's C# coding standard (v1.81) <http://www.idesign.net/idesign/download/IDesign CSharp Coding Standard.zip> and read the following guideline 4.4.19 (p20)

"Do not use volatile variables, ...

Notice that Juval doesn't write "Avoid ...". He should probably have said "Avoid"

Tom

----- Jon Skeet [C# MVP] wrote: ----

TT (Tom Tempelaere) <"=?Utf-8?B?VFQgKFRvbSBUZW1wZWxhZXJlKQ==?=" <_N
0SPA|/\|[email protected]|/\|APS0_N_>> wrote
What you say is true, and I agree with you. Perhaps I'm stil
struggling too much with my c++ background. But I will have to tak
extra care not to mix the C# volatile with volatile in C/C++ when
have to do another project in C++. But that is part of the job
guess. I have to constantly be aware of these issues, because I'
dealing with different languages all the time. Another fact is that
lot of C# coders have a C++ background, and it is worth mentionin
the difference of volatile in these languages because the languages loo
similar. That's why I mentioned it

Right. However, treating *anything* as the same between two languages
is a potential problem. That's why I rigorously try to stick with the
idioms, naming conventions etc of a new language - it helps me to think
in that language, rather than one which happens to look like it :
I do (of course) hide any specifics of the event to the client, s
that is not an issue. Asking the thread to finish is just calling
method, checking whether shutdown was requested is just another. The
one can implement it like he wants
name. I agree that testing a boolean is more readable than waiting
Right

When you speak of locking, you mean that you would use a lockin
object to access the boolean instead of making it volatile? Like
lock( lockObject ) { stopRunning= true;
lock( lockObject ) { if(stopRunning) {...}

Nope, that's exactly it. I'd put the actual lock within the property,
but yes, that's the thing. The semantics of "lock" include a read
memory barrier when acquiring, and a write memory barrier when
releasing, so that you get volatile behaviour
 
TT (Tom Tempelaere) <"=?Utf-8?B?VFQgKFRvbSBUZW1wZWxhZXJlKQ==?=" <_N_
0SPA|/\|[email protected]|/\|APS0_N_> said:
I do not wish to reopen this discussion. But I was just browsing
through IDesign's C# coding standard (v1.81)
<http://www.idesign.net/idesign/download/IDesign CSharp Coding%2
0Standard.zip> and read the following guideline 4.4.19 (p20):

"Do not use volatile variables, ..."

Notice that Juval doesn't write "Avoid ...". He should probably have
said "Avoid".

Indeed. There are sufficiently many other things which I disagree about
in those coding standards that I'm not going to go through them one by
one though :)

(I would go along with it as "avoid" though, in this case, favouring
explicit locking. I wouldn't lock on "this" though, as they do.)
 
Back
Top