==5172== Possible data race during write of size 4 at 0x600C90 by thread #3 ==5172== Locks held: none ==5172== at 0x40065F: incr_count (in /home/hungming/a) ==5172== by 0x4C2DB38: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==5172== by 0x4E3BE99: start_thread (pthread_create.c:308) ==5172== ==5172== This conflicts with a previous write of size 4 by thread #2 ==5172== Locks held: none ==5172== at 0x40065F: incr_count (in /home/hungming/a) ==5172== by 0x4C2DB38: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==5172== by 0x4E3BE99: start_thread (pthread_create.c:308)
上面這編列出可能有data-race的情形。
==5172== Thread #5: lock order “0x600CA0 before 0x600CC8” violated ==5172== ==5172== Observed (incorrect) order is: acquisition of lock at 0x600CC8 ==5172== at 0x4C2DFCD: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==5172== by 0x4006FB: lock_m2_then_m1 (in /home/hungming/a) ==5172== by 0x4C2DB38: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==5172== by 0x4E3BE99: start_thread (pthread_create.c:308) ==5172== ==5172== followed by a later acquisition of lock at 0x600CA0 ==5172== at 0x4C2DFCD: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==5172== by 0x40070B: lock_m2_then_m1 (in /home/hungming/a) ==5172== by 0x4C2DB38: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==5172== by 0x4E3BE99: start_thread (pthread_create.c:308)
WARNING: ThreadSanitizer: data race (pid=4441) Location is global ‘Global’ of size 4 at 0x7f4d31e90ad8 (a+0x0000016caad8) SUMMARY: ThreadSanitizer: data race ??:0 Thread2
class ObjFactory { map<string, weak_ptr<Obj>> lookup_; public: shared_ptr<Obj> get(const string &name) { auto it = lookup_.find(name); if (it != lookup_.end()) { shared_ptr<Obj> obj((it->second).lock()); return obj; } shared_ptr<Obj> instance(new Obj(name)); weak_ptr<Obj> obj(instance); lookup_[name] = obj; return instance; } };
看起來沒什麼問題,不過譽到以下這種情況就爛了
1 2 3 4 5 6 7 8 9 10
for (int i = 0; i < 3; i++) { shared_ptr<Obj> s = pFactory->get("HM"); if (s) { cout << "create new obj" << endl; } else { cout << "cannot create new obj" << endl; } }
int func() { static int i, state = 0; switch (state) { case 0: goto LABEL0; case 1: goto LABEL1; } LABEL0: for (i = 0; i < 10; i++) { state = 1; return i; LABEL1:; } return -1; }