Do I need insert fence before "p = tmp" to avoid memory reordering? Is it possible "p=tmp" executed before "(*tmp)[1]=2" due to memory reordering from the view of thread 2 without using fence/atomic/mutex?
thread 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;
thread 2
extern const std::map<int, int>* p; // suppose p initalized with {{1:2}}
assert(p->find(1)->second == 2);
Is it possible "p=tmp" executed before "(*tmp)[1]=2" due to memory reordering from the view of thread 2 without using fence/atomic/mutex?
can it happen yes
volatile should be added to the list of things preventing the reordering but volatile would still not protect from the data race
Do I need insert fence before "p = tmp" to avoid memory reordering?
you need to add a synchronization but fences are often suboptimal and were they are needed is architecture specific. atomic would be better suited in that case
with #include <atomic>
thread 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;
thread 2
extern std::atomic<const std::map<int, int>*> p; // suppose p initalized with {{1:2}}
assert(p->find(1)->second == 2);
You have thread 2 to wait for thread 1 to complete its chunk of work
thread 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
thread 2
extern const std::map<int, int>* p; // suppose p initalized with {{1:2}}
// wait for event here
assert(p->find(1)->second == 2);
or you can guard p with CS or mutex in both threads but then p should be checked for validity before usage in thread 2
thread 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
thread 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.