==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; }
int main() { IntVector v; for (int i = 0; i < 100; i++) v.set(i, i); transform(v.begin(), v.end(), v.begin(), [](int v) { return v * 2; }); for (int& i : v) { i *= 2; } for (const int& i : v) { cout << i << endl; } }
// Send the sequence 2, 3, 4, ... to channel 'ch'. func Generate(ch chan<- int) { for i := 2; ; i++ { ch <- i // Send 'i' to channel 'ch'. } }
// Copy the values from channel 'in' to channel 'out', // removing those divisible by 'prime'. func Filter(in <-chan int, out chan<- int, prime int) { for { i := <-in // Receive value from 'in'. if i%prime != 0 { out <- i // Send 'i' to 'out'. } } }
// The prime sieve: Daisy-chain Filter processes. func main() { ch := make(chan int) // Create a new channel. go Generate(ch) // Launch Generate goroutine. for i := 0; i < 10; i++ { prime := <-ch fmt.Println(prime) ch1 := make(chan int) go Filter(ch, ch1, prime) ch = ch1 } }