甚至在使用std::原子类型后也遇到了种族歧视

Encountered race even after using std::atomic types

本文关键字:类型 遇到 种族歧视 std      更新时间:2023-10-16

你能告诉我以下代码是否是线程安全的吗?

我想我遇到了一个竞争条件,因为即使我已经从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加载。

我看到的情况是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都应该执行

我在这里找不到任何真正的竞争条件,但我认为这段代码可能无法在所有操作系统上正常运行。

让我们看看提高收益率可以解决问题。

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();
    }
}