Will a calling thread see modifications to local variables after thread.join()?

天大地大妈咪最大 提交于 2019-12-23 12:13:31

问题


In the simplest possible example, let's say I have a function that starts a thread, which in turn sets the value of a local variable to true. We join the thread, then leave the function.

bool func() {
    bool b = false;
    std::thread t([&]() { b = true; }); 
    t.join();
    return b;
}

Will this function return true, or is the behavior undefined?


回答1:


Yes, it must return true.

[thread.thread.member]

void join();

4 Effects: Blocks until the thread represented by *this has completed.

5 Synchronization: The completion of the thread represented by *this synchronizes with ([intro.multithread]) the corresponding successful join() return.

So the execution of the thread represented by the handle, and associated side effects are done before join returns to the calling context.

Example

Let's look at two functions, which differ only in when they join a thread:

int count_A() {
    int counter = 0;
    bool flag(true);
    auto t = std::thread([&]{flag = false;});

    while(flag) {    // infinite loop - flag never synchronized
        ++counter;
    }
    t.join();        // joins thread after loop exits
    return counter;
}
int count_B() {
    int counter = 0;
    bool flag(true);
    auto t = std::thread([&]{flag = false;});

    t.join();       // joins thread before loop, forcing synchronization
    while(flag) {
        ++counter;
    }
    return counter;
}

When compiled with g++ version 8.2 at -O3 optimization, invoking count_A results in an infinite loop because the compiler assumes flag is always true.

On the other hand, invoking count_B will just return a value of 0. Because the value of flag is checked after thread.join(), it's value is re-loaded, and flag is false so the while loop doesn't execute.

Note that if flag is changed to an atomic_bool, then count_A has the intended behavior of incrementing the counter until the flag is set to false, and the function does not enter an infinite loop (instead returning once flag is set to false by the child thread).



来源:https://stackoverflow.com/questions/55932983/will-a-calling-thread-see-modifications-to-local-variables-after-thread-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!