c++c++14data-race

Reasoning about a program containing a data race


This question follows in continuation of my previous question where my understanding became that 'A data race is a property of an execution, not of the program in the abstract' which means that as long as 2 threads don't access the shared variable(with atleast one being a write access), in reality and not just theoretically, then the behaviour of the program will be well defined.

In light of the above understanding, I want to discuss the following program:

#include <iostream>
#include <thread>
#include <unistd.h>

constexpr int sleepTime = 10;

void func(int* ptr) {
    sleep(sleepTime);
    std::cout<<"going to delete ptr: "<<(uintptr_t)ptr<<"\n";
    delete ptr;
    std::cout<<"ptr has been deleted\n";
}

int main() {

    int* l_ptr = new int(5);

    std::thread t(func, l_ptr);

    t.detach();


    std::cout<<"We have passed ptr: "<<(uintptr_t)l_ptr<<" to thread for deletion. Val at ptr: "<<*l_ptr<<"\n";

    std::cin.get();

}

The above program contains a data race iff the 'main thread' and the 'child thread' happens to access the shared variable at the same time.

However, isn't it reasonable to say atleast that this is highly unlikely to happen in reality while working with multi-core CPUs.


Solution

  • The above program contains a data race, full stop.

    There are accesses to the same object on two threads that are unsequenced to one another. It isn't a question of "at the same time".

    The standard defines a relation Happens-Before, which only barely relates to the wall-clock time when things happen.

    Undefined behaviour doesn't mean "bad things are observed to happen". It means you can't reason about what you observe to happen from the rules of C++.