我们可以使用 c++20 的atomic_ref来并发访问用户类型成员函数吗?



考虑这个问题:我有一个用户类型的atomic_ref。我想同时访问它的成员函数。参见以下代码:

struct A{
int counter=0;

int add(){
++counter;
return counter;
};
};
int main() { 
A a;
std::atomic_ref<A> ra{a};
std::vector<std::thread> v;
for(int i=0;i<1000;++i){
v.emplace_back([&ra]{ra.load().add();});
};
for(auto & t: v){t.join();};
std::cout<<a.counter<<std::endl;
};

最终输出是0,因为load()返回一个副本。有没有其他方法可以通过atomic_ref得出正确的结果?

我还想问,如果我们有一个atomic_ref<T*>,我们可以使用load()来访问成员函数,例如ra.load()->add()吗。它安全吗?代码将变成这样:

struct A{
int counter=0;

int add(){
++counter;
return counter;
};
};
int main() { 
A* a=new A;
std::atomic_ref<A*> ra{a};
std::vector<std::thread> v;
for(int i=0;i<1000;++i){
v.emplace_back([&ra]{ra.load()->add();}); //Accessing member functions.
};
for(auto & t: v){t.join();};
std::cout<<a->counter<<std::endl;
};

在我的测试中,它确实是1000,这是正确的。

原子不是魔法。它们只影响引用本身的加载和访问,而不影响通过引用访问的任何内容。

最新更新