即使在使用std :: atomic类型之后也遇到了竞争

时间:2014-08-28 04:44:49

标签: c++ multithreading c++11 thread-safety atomic

如果以下代码是线程安全的,请告诉我吗?

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

2 个答案:

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