这个问题是我的上一个问题的延续,我的理解是“
A data race is a property of an execution, not of the program in the abstract
”,这意味着只要2个线程不访问共享变量(至少有一个是写访问),实际上 而不仅仅是理论上,那么程序的行为将得到很好的定义。
根据上述理解,我想讨论以下方案:
#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();
}
如果“主线程”和“子线程”恰好同时访问共享变量,则上述程序包含数据竞争。
但是,至少可以合理地说,在使用多核 CPU时,这种情况“极不可能”在现实中发生。
两个线程上对同一对象的访问彼此不排序。这不是“同时”的问题。
该标准定义了一个关系
Happens-Before,它只与事情发生时的挂钟时间几乎没有关系。 未定义的行为并不意味着“观察到不好的事情发生”。这意味着您无法根据 C++ 规则推断您观察到的情况。
应用您的理解是正确的。您对这种理解的
不是:
如果“主线程”和“子线程”恰好同时访问共享变量,则上述程序包含数据竞争。同时数据竞争并不是要访问“共享变量
”。它们是在没有适当同步的情况下访问内存,因此两次访问之间不存在“发生之前”关系。 在其他线程中删除指针和在主线程中使用它之间没有这种关系。因此,这段代码存在数据竞争。该数据竞争是其执行的一个属性,并且该执行具有数据竞争,因为该执行不包含任何会“阻止”发生数据竞争的内容。它有两种访问,其中一种是写入,它们之间没有发生之前的排序。
因此,存在数据竞争。