debug vs. release

Hi!

I am using the Microsoft Visual Studio to build a program that has several threads. The threads communicate among them reading a shared variable; thus, a thread is waiting: "while (variable == 0);", until other thread puts the variable into 1. That occurs more than one time in the program, and everything works fine in the Debug version. However, the Release version does not get out from the while bucle. I have tried some changes like:

while (variable == 0)
{
cout << ".";
}

instead of the previous:

while (variable == 0);

And it works fine in this way. I would like to know why this happens, whether there is any conflict between the variables or why, perhaps, the condition is not read again and again.

Although the program works, I would like to remove all these couts. Anybody knows how could I improve this question?

Thank you very much,

xagutxu
Wrong. You need to use a "synchronization object".

You can't use a variable. I keep telling folk to read up on the issues before writing code. You can't instruct the computer if you yourself don't know what to do!
http://www.cplusplus.com/forum/windows/14336/
OK, I admit that I don't know very much about "synchronization objects", and thank you for the link.

However, I think you have exceeded saying that "if you yourself don't know what to do!". What I don't know is "HOW to do". Nevertheless, thanks for you opinion.

xagutxu
No offence meant. But there are a number of issues associated with multithreaded programming. And in my experience, many folk just dive in a start coding without taking the time to understand them, then only pause for thought when the code behaves unexpectedly.

I'm a firm believer that the concepts should be understood before use.
I'm sure that you're right.

However, I would like to explain you a thing that has surprised me.

One thread writes on a variable, and the other is reading in a While loop. So, there is no concurrency conflict, because only one writes on it (isn't there...?). I don't think this is a concurrency problem, or am I wrong (if so, should I use a monitor or the like)?

And another thing: why does it work in Debug version and not in Release version (if the changes mentioned before are not applied)?
A variable may be stored in a register, or cached in a register. In which the code may behave differently if it's updated unexpectedly. The compiler can be told to deal with this by declaring the variable volatile.

e.g. volatile int count;
Technically the volatile keyword doesn't even solve this problem; it just so happens that on
most compilers it does, but the behavior of the compiler in this regard is not mandated by
the standard.

The only sure-fire way to solve the problem is to use a synchronization object such as a
mutex or semaphore.

@xagutxu:

The reason why you see the apparent inexplicable behavior is because when the compiler
sees the code

1
2
3
4
while( some_variable == 0 )
{
   // do nothing
}


the compiler is saying to itself "well, nothing in the loop can ever modify some_variable, so
in theory, I can optimize out the second and all subsequent comparisons, since once I get
into the loop, there is no way to get out of it."

When you put the "cout << '.';" statement in the loop, suddenly the compiler cannot make
that assumption because, in theory ostream& operator<<( char ) could modify
some_variable, so the compiler can no longer elide the comparisons.

OK, jsmith. I have understood.

I have tried with the "volatile" keyword, and it works (could I have any problem with other compilers..?)

The problem I have now is related tightly with this. When I use the release version, all the "while" bucles stop. I capture the data introduced through the micro, and I use the Waveform Audio Structures for this. The program has to wait until a buffer is full, and for that purpose, it looks up the dwFlag of the WAVEHDR structure:

while ((wavehdr2.dwFlags & WHDR_DONE) != TRUE);

In the debug version it works fine, but not in the release one, except I write a "cout" again in the while. I can't declare the WAVEHDR structure as "volatile", because there are some inherent functions that use them (waveInAddBuffer etc.). So, what can I do?

Thank you very much,

Xagutxu

(could I have any problem with other compilers..?)


In theory, yes.

You should really look up semaphores. That is exactly what you need.

The other problem with your approach is that the while loop is a busy loop -- it will consume 100% of the CPU as long as it runs. While it is consuming 100% of the CPU, your other thread -- the one that actually sends the condition to cause the while loop to exit -- doesn't run unless you have a hyperthreaded or multi-core CPU.

Eventually the other thread is given a chance to run since the operating system performs context switches, but all the loop does is introduce additional latency.
Topic archived. No new replies allowed.