configuration:debug result: program exit with code 0.
configuration:release result: main thread infinite loops,wont jump out of the loop(t.n==0 is true).
how can I get out of the loop ?
Only one writer thread,so I didnot use any mutex.
qt5.13 vs2017
main.cpp:
//#include"QtTestProg.h"
#include<QApplication>
#include<QMessageBox>
#include<QThread>
class MyThread :public QThread
{
Q_OBJECT
public:
int n = 0, m = 1;
void run()override;
};
void MyThread::run()
{
for (; m;) {
QThread::msleep(3000);
n = 1;
}
}
int main(int argc, char*argv[])
{
QApplication a(argc, argv);
MyThread t;
t.start();
for (; 1;)
{
if (t.n != 0)
{
break;
}
}
t.m = 0;
t.quit();
t.wait();
return 0;
}
#include"main.moc"
Only one writer thread,so I didnot use any mutex.
That's undefined behavior. If you read and write the same memory location from different threads, you need synchronization. From https://en.cppreference.com/w/cpp/language/memory_model
When an evaluation of an expression writes to a memory location and another evaluation reads or modifies the same memory location, the expressions are said to conflict. A program that has two conflicting evaluations has a data race unless
- both evaluations execute on the same thread or in the same signal handler, or
- both conflicting evaluations are atomic operations (see std::atomic), or
- one of the conflicting evaluations happens-before another (see std::memory_order)
If a data race occurs, the behavior of the program is undefined.
You either need a mutex guarding both reads and writes or use std::atomic_int
/QAtomicInt
instead of plain int
for m
and n
.
As for the consequences of the undefined behavior, here (godbolt) you can see that gcc at O2 level compiles out the loop in the main()
entirely unless you change TYPE
from int
to std::atomic_int
at the top.