26.02.2014 Views

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

More on synchronization<br />

© 2009, <strong>QNX</strong> <strong>Software</strong> <strong>Systems</strong> GmbH & Co. KG.<br />

Don’t be tricked by the prefix pthread_ into thinking that these are POSIX functions<br />

— they’re not.<br />

As described above, a thread needs to wait for something to happen. The most obvious<br />

choice in the list of functions above is the pthread_sleepon_wait(). But first, the<br />

thread needs to check if it really does have to wait. Let’s set up an example. One<br />

thread is a producer thread that’s getting data from some piece of hardware. The other<br />

thread is a consumer thread that’s doing some form of processing on the data that just<br />

arrived. Let’s look at the consumer first:<br />

volatile int data_ready = 0;<br />

consumer ()<br />

{<br />

while (1) {<br />

while (!data_ready) {<br />

// WAIT<br />

}<br />

// process data<br />

}<br />

}<br />

The consumer is sitting in its main processing loop (the while (1)); it’s going to do<br />

its job forever. The first thing it does is look at the data_ready flag. If this flag is a 0,it<br />

means there’s no data ready. Therefore, the consumer should wait. Somehow, the<br />

producer will wake it up, at which point the consumer should reexamine its<br />

data_ready flag. Let’s say that’s exactly what happens, and the consumer looks at the<br />

flag and decides that it’s a 1, meaning data is now available. The consumer goes off<br />

and processes the data, and then goes to see if there’s more work to do, and so on.<br />

We’re going to run into a problem here. How does the consumer reset the data_ready<br />

flag in a synchronized manner <strong>with</strong> the producer? Obviously, we’re going to need<br />

some form of exclusive access to the flag so that only one of those threads is<br />

modifying it at a given time. The method that’s used in this case is built <strong>with</strong> a mutex,<br />

but it’s a mutex that’s buried in the implementation of the sleepon library, so we can<br />

access it only via two functions: pthread_sleepon_lock() and<br />

pthread_sleepon_unlock(). Let’s modify our consumer:<br />

consumer ()<br />

{<br />

while (1) {<br />

pthread_sleepon_lock ();<br />

while (!data_ready) {<br />

// WAIT<br />

}<br />

// process data<br />

data_ready = 0;<br />

pthread_sleepon_unlock ();<br />

}<br />

}<br />

Now we’ve added the lock and unlock around the operation of the consumer. This<br />

means that the consumer can now reliably test the data_ready flag, <strong>with</strong> no race<br />

conditions, and also reliably set the flag.<br />

60 Chapter 1 • Processes and Threads April 30, 2009

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!