Other replies have already pointed out in detail what the instruction does, but just to recap that, since y
(or head
in the linked example) is declared as volatile
changes made to that variable from a different thread will cause the while
loop to finish once the condition has been met.
However, even though the linked code example is very short, it's a near perfect example of how NOT to write code.
First of all the line
while( tail > head );
will waste enormous amounts of CPU cycles, pretty much locking up one core until the condition has been met.
The code gets even better as we go along.
buffer[head++ % N] = item;
Thanks to JAB for pointing out i mistook post- with pre-increment here. Corrected the implications.
Since there are no lock
s or mutex
es we obviously will have to assume the worst. The thread will switch after assigning the value in item
and before head++
executes. Murphy will then call the function containing this statement again, assigning the value of item
at the same head
position.
After that head
increments. Now we switch back to the first thread and increment head
again. So instead of
buffer[original_value_of_head+1] = item_from_thread1;
buffer[original_value_of_head+2] = item_from_thread2;
we end up with
buffer[original_value_of_head+1] = item_from_thread2;
buffer[original_value_of_head+2] = whatever_was_there_previously;
You might get away with sloppy coding like this on the client side with few threads, but on the server side this could only be considered a ticking time bomb. Please use synchronisation constructs such as lock
s or mutex
es instead.
And well, just for the sake of completeness, the line
while( tail > head );
in the method pop_back()
should be
while( tail >= head );
unless you want to be able to pop one more element than you actually pushed in (or even pop one element before pushing anything in).
Sorry for writing what basically boils down to a long rant, but if this keeps just one person from copying and pasting that obscene code it was worth while.
Update: Thought i might as well give an example where a code like while(x>y);
actually makes perfect sense.
Actually you used to see code like that fairly often in the "good old" days. cough DOS.
Was´nt used in the context of threading though. Mainly as a fallback in case registering an interrupt hook was not possible (you kids might translate that as "not possible to register an event handler").
startAsynchronousDeviceOperation(..);
That might be pretty much anything, e.g. tell the hardisk to read data via DMA, or tell the soundcard to record via DMA, possibly even invoke functions on a different processor (like the GPU). Typically initiated via something like outb(2)
.
while(byteswritten==0); // or while (status!=DONE);
If the only communication channel with a device is shared memory, then so be it. Wouldnt expect to see code like that nowadays outside of device drivers and microcontrollers though. Obviously assumes the specs state that memory location is the last one written to.