Re: Need Thread Advice

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



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
.



Relevant Pages

  • Re: Threading and Serial port issue
    ... I am using the Opennetcf Port class to handle the serial comms. ... I then sit in a loop waiting for data to arrive. ... private void SetupBoard_Click ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: Event Driven State Machine
    ... Place the case statement in an infinite loop, ... of it's own (aside from the occasional serial clock) it has to operate ... -- Defined as I2C Master Start Sequence ... -- Transmit the acknowledge ...
    (comp.lang.vhdl)
  • Re: Serial Communication Problem
    ... I have no problems reading from a serial port within a sub-thread. ... the basic loop within the thread, ... > The problem is that function WaitCommEvent never return! ...
    (microsoft.public.windowsxp.embedded)
  • SSA Cabling and Adapter problem
    ... A2 -> Port 16 ... So the A loop is fine, ... The server is an S7A with two I/O drawers, ... There is a seventh adapter in the server, not connected to any disks at all, ...
    (AIX-L)
  • Re: serial port question.
    ... Note that you have left the port in non-blocking mode. ... the termios settings are for raw mode and the VTIME and VMIN ... dependent upon that configuration, and when used as an example ... necessarily must be in a loop. ...
    (comp.os.linux.hardware)