如果以下代码是线程安全的,请告诉我吗?
我认为我遇到了竞争条件,因为即使我已经从GUI将params.b的值设置为true,Task2也不会被执行。
struct params {
params() {}
~params() {}
atomic_bool a;
atomic_bool b;
};
struct driver {
driver() {}
~driver() {}
params myParams;
void tFun() {
while (1) {
if (myParams.a) { /* DoTask1 */ }
if (myParams.b) { /* DoTask2 */ }
}
}
void DoSome() {
std::thread t(&driver::tFun, this);
t.detach();
while (1) {
myParams.a = fromGui.val;
myParams.b = fromGui.val;
}
}
};
int main() {
driver myDriver;
myDriver.DoSome();
return 0;
}
请执行我的' fromGui.val'用法,它应该表明这个值将从GUI加载。
答案 0 :(得分:1)
我可以看到的情况是fTun()
函数和DoSome()
之间存在竞争:
例如:
1. DoSome() sets a,b true
2. tFun() executes in while loop, as a is true, it starts DoTask1
2. DoSome() sets a,b to false
3. tFun() finishes DoTask1 and come to check myParams.b which is false;
DoTask2 is ignored!!
4. loop continues to step 1
如果你总是将a,b设置为true,那么就没有可比较的种族,任务DoTask1 & DoTask2
都应该被执行
答案 1 :(得分:-2)
我在这里找不到任何真实的竞争条件,但我相信这些代码可能无法在所有操作系统上正常运行。
让我们看看一些收益率可以解决这个问题。
void tFun() {
while (1) {
bool nop = false;
if (myParams.a) { /* DoTask1 */ }
else { nop = true; }
if (myParams.b) { /* DoTask2 */ }
else { nop = true; }
if (nop) { std::this_thread::yield(); }
}
}
void DoSome() {
std::thread t(&driver::tFun, this);
t.detach();
while (1) {
myParams.a = fromGui.val;
myParams.b = fromGui.val;
std::this_thread::yield();
}
}