Home > front end >  thread::detach during concurrent thread::join in C
thread::detach during concurrent thread::join in C

Time:10-24

In the following program, during one thread (main) is performing thread::join, another thread (x) calls thread::detach:

#include <thread>
#include <iostream>

int main(void) {
    auto t = std::thread([] {
        std::this_thread::sleep_for( std::chrono::milliseconds(1000) );
    } );
    auto x = std::thread([&t] {
        std::this_thread::sleep_for( std::chrono::milliseconds(500) );
        if ( t.joinable() )
        {
            std::cout << "detaching t..." << std::endl;
            t.detach();
        }
    } );
    std::cout << "joining t..." << std::endl;
    t.join();
    x.join();
    std::cout << "Ok" << std::endl;
    return 0;
}

It work fine in GCC's libstdc and Clang's libc printing

joining t...
detaching t...
Ok

but in Visual Studio the program terminates with not-zero exit code before printing Ok. Online demo: https://gcc.godbolt.org/z/v1nEfaP7a

Is it a bug in Visual Studio or the program contains some undefined behavior?

CodePudding user response:

Neither join nor detach are const-qualified and therefore the implementation is allowed to modify internal memory of the thread object without having to provide any guarantees of write/write or write/read data race avoidance on unsynchronized calls to these member functions per the default data race avoidance requirements of [res.on.data.races].

There is also no exception to this rule mentioned in [thread.threads] or anywhere else for these functions.

Therefore calling join and detach without establishing a happens-before relation between the two calls is a data race and causes undefined behavior.

Even without the detach call, there is still a write/read data race on the join/joinable pair of calls.

  • Related