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