我是否需要在“ p = tmp”之前插入篱笆以避免内存重新排序?由于从线程2的角度对内存进行了重新排序,而不使用fence / atomic / mutex,是否有可能在“(* tmp)[1] = 2”之前执行“ p = tmp”?
线程1
extern const std::map<int, int>* p;
auto tmp = new std::map<int, int>;
(*tmp)[1] = 2;
...
(*tmp)[2] = 3;
// do I need insert fence here to make sure above operation on tmp ready before tmp assigned to p?
p = tmp;
线程2
extern const std::map<int, int>* p; // suppose p initalized with {{1:2}}
assert(p->find(1)->second == 2);
答案 0 :(得分:2)
由于内存的原因,是否有可能在“(* tmp)[1] = 2”之前执行“ p = tmp” 从线程2的角度重新排序,而无需使用fence / atomic / mutex?
会发生吗
应该将volatile添加到阻止重新排序的内容列表中,但是volatile仍然不能避免数据争夺
我是否需要在“ p = tmp”之前插入篱笆以避免内存重新排序?
您需要添加同步,但是篱笆通常不是最理想的,需要使用的是特定于体系结构的。原子在这种情况下会更适合
与#include <atomic>
线程1
extern std::atomic<const std::map<int, int>*> p;
auto tmp = new std::map<int, int>;
(*tmp)[1] = 2;
...
(*tmp)[2] = 3;
// do I need insert fence here to make sure above operation on tmp ready before tmp assigned to p?
p = tmp;
线程2
extern std::atomic<const std::map<int, int>*> p; // suppose p initalized with {{1:2}}
assert(p->find(1)->second == 2);
答案 1 :(得分:1)
您有线程2等待线程1完成其工作
线程1
extern const std::map<int, int>* p;
auto tmp = new std::map<int, int>;
(*tmp)[1] = 2;
...
(*tmp)[2] = 3;
p = tmp;
// set event here
线程2
extern const std::map<int, int>* p; // suppose p initalized with {{1:2}}
// wait for event here
assert(p->find(1)->second == 2);
或者您可以在两个线程中使用CS或互斥锁保护 p ,但是在线程2中使用p之前,应先检查p的有效性
线程1
extern const std::map<int, int>* p;
auto tmp = new std::map<int, int>;
// lock mutex here
(*tmp)[1] = 2;
...
(*tmp)[2] = 3;
p = tmp;
// unlock mutex here
线程2
extern const std::map<int, int>* p; // suppose p initalized with {{1:2}}
// lock mutex here
// check if p is initialized:
// if (p is ok){
assert(p->find(1)->second == 2);
// }
// unlock mutex here