Hi all,

I have a console C++ app (VC++ 6.0, WIN XP x64) with 1 worker thread created
with _beginthreadex in addition to the main thread of execution (so 2
threads).

The worker thread should carry on until the main thread says stop.

At the moment I have implemented this by having the main thread set a bool
visible to both threads to true (it is initialised to false at startup).
The worker thread simply checks the value of this bool on each iteration of
it's loop and keeps going until it is true. Then, the worker thread cleans
up after itself and returns.

Here is some pseudoish code:

bool stopThread = false;
bool threadStopped = false;

int main (void)
{
createThread();

// do stuff for a while

stopThread = true;

while (threadStopped == false)
{
// wait
};

// do other stuff and exit

}


void thread(void)
{
while (stopThread == false)
{
// do stuff
}

// cleanup

threadStopped = true;
return;
}

As far as I can see this should be fine and perfectly safe (i.e. I do not
need any synchronisation in terms of critical sections, mutexes, semaphores,
events etc..) because each variable is only written by one thread.

Am I right?

Is there a better way with better style etc that isn't overkill?

Many thanks for your time,

Dave

Re: Do I need synchronisation for 1 writer, 1 reader thread? by William

William
Fri Aug 19 09:57:17 CDT 2005

"Dave" <dave@nowhere.com> wrote in message
news:e2$1nPMpFHA.3512@TK2MSFTNGP15.phx.gbl...
> I have a console C++ app (VC++ 6.0, WIN XP x64) with 1 worker thread
> created
> with _beginthreadex in addition to the main thread of execution (so 2
> threads).
>
> The worker thread should carry on until the main thread says stop.
>
> At the moment I have implemented this by having the main thread set a bool
> visible to both threads to true (it is initialised to false at startup).
> The worker thread simply checks the value of this bool on each iteration
> of
> it's loop and keeps going until it is true. Then, the worker thread cleans
> up after itself and returns.
> ...
>
> As far as I can see this should be fine and perfectly safe (i.e. I do not
> need any synchronisation in terms of critical sections, mutexes,
> semaphores,
> events etc..) because each variable is only written by one thread.
>
> Am I right?
>
> Is there a better way with better style etc that isn't overkill?

On a 32 bit x86 machine it will work just fine. On other processors, say the
IA64, it won't work as well. For the details google for terms like "memory
barrier" or "memory access ordering" for the details.

A quick fix is to replace the boolean with an integer where 0 means false.
Use InterlockedIncrement() to change the value to true (1).

Regards,
Will




Re: Do I need synchronisation for 1 writer, 1 reader thread? by Doug

Doug
Fri Aug 19 11:01:38 CDT 2005

On Fri, 19 Aug 2005 15:42:32 +0200, "Dave" <dave@nowhere.com> wrote:

>Hi all,
>
>I have a console C++ app (VC++ 6.0, WIN XP x64) with 1 worker thread created
>with _beginthreadex in addition to the main thread of execution (so 2
>threads).
>
>The worker thread should carry on until the main thread says stop.
>
>At the moment I have implemented this by having the main thread set a bool
>visible to both threads to true (it is initialised to false at startup).
>The worker thread simply checks the value of this bool on each iteration of
>it's loop and keeps going until it is true. Then, the worker thread cleans
>up after itself and returns.
>
>Here is some pseudoish code:
>
>bool stopThread = false;
>bool threadStopped = false;
>
>int main (void)
>{
> createThread();
>
> // do stuff for a while
>
> stopThread = true;
>
> while (threadStopped == false)
> {
> // wait
> };
>
> // do other stuff and exit
>
>}
>
>
>void thread(void)
>{
> while (stopThread == false)
> {
> // do stuff
> }
>
> // cleanup
>
> threadStopped = true;
> return;
>}
>
>As far as I can see this should be fine and perfectly safe (i.e. I do not
>need any synchronisation in terms of critical sections, mutexes, semaphores,
>events etc..) because each variable is only written by one thread.
>
>Am I right?

No. When you have multiple threads in a read/write situation, you need
synchronization. You may be able to cheat, though, depending on the machine
architecture and the atomicity of your data access. Concerning your bools,
you're relying on your loop bodies to do something that prevents the
compiler from optimizing the loop condition tests out of existence. At the
very least you should make them volatile, but see these messages for more
on why that's at best a band-aid for the problem:

http://groups.google.com/groups?selm=7hl7205u4ksejokc9ormufeo02pb9i1stu%404ax.com
http://groups.google.com/groups?selm=k7fa209epgjcn2rep0rqks2ee0f4jcitgu%404ax.com

Even with volatile, your method may be unreliable on machines that require
memory barriers for reasons given in the second message.

>Is there a better way with better style etc that isn't overkill?

I don't know what you would consider overkill, but there are alternatives
that offer correctness and increased capabilities. See the little FAQ I
wrote for more:

http://members.cox.net/doug_web/threads.htm

Also, I don't see where you wait on the secondary thread to exit, so you
have a race condition there; the FAQ talks about why it's important to join
with your threads before exiting main.

--
Doug Harrison
VC++ MVP

Re: Do I need synchronisation for 1 writer, 1 reader thread? by Joe

Joe
Fri Aug 19 15:37:43 CDT 2005

1) Do not wait in main() for (threadStopped == TRUE), because it is not
actually true... it is actually still running, and main() start its exit
process before the thread has actually finished, in which case it will be
abruptly terminated.

Instead, use WaitForSingleObject() on the thread-handle returned by
_beginthreadex().

If your thread function was written in C++ and did any real work, then there
will probably be some destructors to run after it sets threadStopped to
TRUE, which is not necessarily obvious by looking at the code.



"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:tdvbg1de8pgb3rv2aio69878ngmq45kuf3@4ax.com...
> On Fri, 19 Aug 2005 15:42:32 +0200, "Dave" <dave@nowhere.com> wrote:
>
> >Hi all,
> >
> >I have a console C++ app (VC++ 6.0, WIN XP x64) with 1 worker thread
created
> >with _beginthreadex in addition to the main thread of execution (so 2
> >threads).
> >
> >The worker thread should carry on until the main thread says stop.
> >
> >At the moment I have implemented this by having the main thread set a
bool
> >visible to both threads to true (it is initialised to false at startup).
> >The worker thread simply checks the value of this bool on each iteration
of
> >it's loop and keeps going until it is true. Then, the worker thread
cleans
> >up after itself and returns.
> >
> >Here is some pseudoish code:
> >
> >bool stopThread = false;
> >bool threadStopped = false;
> >
> >int main (void)
> >{
> > createThread();
> >
> > // do stuff for a while
> >
> > stopThread = true;
> >
> > while (threadStopped == false)
> > {
> > // wait
> > };
> >
> > // do other stuff and exit
> >
> >}
> >
> >
> >void thread(void)
> >{
> > while (stopThread == false)
> > {
> > // do stuff
> > }
> >
> > // cleanup
> >
> > threadStopped = true;
> > return;
> >}
> >
> >As far as I can see this should be fine and perfectly safe (i.e. I do not
> >need any synchronisation in terms of critical sections, mutexes,
semaphores,
> >events etc..) because each variable is only written by one thread.
> >
> >Am I right?
>
> No. When you have multiple threads in a read/write situation, you need
> synchronization. You may be able to cheat, though, depending on the
machine
> architecture and the atomicity of your data access. Concerning your bools,
> you're relying on your loop bodies to do something that prevents the
> compiler from optimizing the loop condition tests out of existence. At the
> very least you should make them volatile, but see these messages for more
> on why that's at best a band-aid for the problem:
>
>
http://groups.google.com/groups?selm=7hl7205u4ksejokc9ormufeo02pb9i1stu%404ax.com
>
http://groups.google.com/groups?selm=k7fa209epgjcn2rep0rqks2ee0f4jcitgu%404ax.com
>
> Even with volatile, your method may be unreliable on machines that require
> memory barriers for reasons given in the second message.
>
> >Is there a better way with better style etc that isn't overkill?
>
> I don't know what you would consider overkill, but there are alternatives
> that offer correctness and increased capabilities. See the little FAQ I
> wrote for more:
>
> http://members.cox.net/doug_web/threads.htm
>
> Also, I don't see where you wait on the secondary thread to exit, so you
> have a race condition there; the FAQ talks about why it's important to
join
> with your threads before exiting main.
>
> --
> Doug Harrison
> VC++ MVP



Re: Do I need synchronisation for 1 writer, 1 reader thread? by Dave

Dave
Mon Aug 22 02:16:45 CDT 2005

Hi All,

Many thanks for your quick and detailed responses.

I figured that my original solution was a bit lazy for the task!

So, I have implemented a solution based on an event synch object and
WaitForSingleObject that works very nicely and allows complete
synchronisation without any dubiousness.

Thanks again to all.

Dave