Re: Need Thread Advice
- From: "mike" <nospamplease.com>
- Date: Wed, 29 Mar 2006 12:35:55 -0500
Thanks, The event object concept seems more reasonable. I will try that.
"Doug Harrison [MVP]" <dsh@xxxxxxxx> wrote in message
news:q2cl22l14edhn05qtrq6mvequre9b99mql@xxxxxxxxxx
On Wed, 29 Mar 2006 10:36:11 -0500, "mike" <nospamplease.com> wrote:
I have an application that utilizes 2 threads for communications; 1 for
receive and 1 for transmit. The threads are derived classes of CWinThread.
The code is written so that when a button is clicked, I open a com port
and
immediately send data out the port. There was a timing problem in that
when
the port was opened, the threads were not running at the time that the
transmit operation was begun. To overcome this, I added a Ready flag in
the
threads and when I open the port, I check this flag to make sure the
thread
is running before exiting the open com function.
/* pseudo code */
OpenCom()
{
/*... open comm stuff */
pthread = CreateThread(......);
pthread->ResumeThread();
while ( !pthread->Ready ) ;
}
The debug code worked ok, but the release code hung in the while() loop. I
realized I had to free up time for the thread so I changed it to
while ( !pthread->Ready ) Sleep(5);
This seems to work. My question is, is there a better way to accomplish
this.
Yes. Your while-loop is what is known as a "busy loop". It is a loop that
consumes all CPU cycles for no good reason, and it should be replaced with
a method that isn't such a resource hog. The "better method" in this case
might involve an event object and WaitForSingleObject. As for your
debug/release mode discrepancy, consider that your loop calls no function
that could change pthread->Ready. In Release mode, the optimizer notices
this and assumes the variable never changes after the first time it tests
it. That is, it probably copies the variable into a register and checks
the
contents of the register from then on, and the result is an infinite loop
if Ready contained false at the moment it was copied to a register. You
could "solve" this problem by declaring Ready volatile, but there are much
better ways, such as using an event object. Note that while volatile is a
little less work, it doesn't do anything about the busy loop, and on some
multiprocessor architectures, there can be an indefinite delay between the
time one thread changes Ready and another thread notices the change. The
reason for this is volatile typically does not have the correct memory
barrier semantics for multithreaded programming, which can lead to some
very weird situations for threads executing on different CPUs.
--
Doug Harrison
Visual C++ MVP
.
- References:
- Need Thread Advice
- From: mike
- Re: Need Thread Advice
- From: Doug Harrison [MVP]
- Need Thread Advice
- Prev by Date: Re: Dead in FreeLibrary()
- Next by Date: Re: a small COM to custom IE printing from JSP,shareware.
- Previous by thread: Re: Need Thread Advice
- Next by thread: CTabCtrl focus MS VC++ 6.0
- Index(es):
Relevant Pages
|