昨天的範例中,看到了Race Condition的現象.
用以下的圖,來表示2個goroutine與資源之間的動態,
以利了解Race Condition的發生原因.
runtime.Gosched() 會讓goroutine釋放處理器資源,
也就是說,切換讓另一個goroutine可以作業.
step 油達大師 九陰真經 玉面飛鷹
---------------------------------------------
1 讀取內容 <-- 九陰真經
2 Gosched() 九陰真經 --> 讀取內容
3 增加內容 Gosched()
4 寫入內容 --> 九陰真經 增加內容
5 (增加了)我也有教 <-- 寫入內容
6 讀取內容 <-- (已增加)
7 Gosched() (已增加) --> 讀取內容
8 增加內容 Gosched()
9 寫入內容 --> (已增加) 增加內容
10 (增加了)只收200 <-- 寫入內容
可以看到玉面飛鷹後來居上,壓掉了油達大師想增加的內容.
那我們要如何偵測Race Condition呢?
我們可以在build程式時,加上 -race
用這樣的方式
go build -race hello74.go
過程:
ll
-rwxrwxr-x. 1 asami asami 1834304 Oct 21 21:17 hello74
-rw-rw-r--. 1 asami asami 841 Oct 22 02:29 hello74.go
go build -race hello74.go
ll
-rwxrwxr-x. 1 asami asami 2599968 Oct 22 19:31 hello74
-rw-rw-r--. 1 asami asami 841 Oct 22 02:29 hello74.go
可以看到Binary檔變大了.
執行結果:
./hello74
==================
WARNING: DATA RACE
Write by goroutine 5:
main.油達大師()
/home/asami/Study2014/S1407/go/hello74/hello74.go:21 +0xd9
Previous read by goroutine 6:
main.玉面飛鷹()
/home/asami/Study2014/S1407/go/hello74/hello74.go:32 +0x5c
Goroutine 5 (running) created at:
main.main()
/home/asami/Study2014/S1407/go/hello74/hello74.go:46 +0x84
Goroutine 6 (running) created at:
main.main()
/home/asami/Study2014/S1407/go/hello74/hello74.go:47 +0x93
==================
真經內容: 欲練此功 我也有教 只收200
Found 1 data race(s)
會偵測到發生Race Condition