File tree Expand file tree Collapse file tree 4 files changed +228
-0
lines changed
examples/singleapp/slice_is_not_threadsafe Expand file tree Collapse file tree 4 files changed +228
-0
lines changed Original file line number Diff line number Diff line change 1+ version : ' 3'
2+
3+ tasks :
4+ fmt :
5+ cmds :
6+ - go fmt ./...
7+ vet :
8+ cmds :
9+ - go vet ./...
10+ run :
11+ cmds :
12+ - cmd : for i in {1..10} ; do go run race/main.go; done
13+ silent : true
14+ run-notrace :
15+ cmds :
16+ - cmd : for i in {1..10} ; do go run notrace/main.go; done
17+ silent : true
18+ run-notrace2 :
19+ cmds :
20+ - cmd : for i in {1..10} ; do go run notrace2/main.go; done
21+ silent : true
22+ run-with-raceoption :
23+ cmds :
24+ - cmd : go run -race race/main.go
25+ ignore_error : true
26+ - go run -race notrace/main.go
27+ - go run -race notrace2/main.go
Original file line number Diff line number Diff line change 1+ // スライス操作 (スライスヘッダの書き換え)はスレッドセーフでは無いというのを示すサンプルです。
2+ // 本サンプルはデータ競合が発生しません。
3+ //
4+ // REFERENCES:
5+ // - https://stackoverflow.com/questions/44152988/append-not-thread-safe
6+ // - https://stackoverflow.com/questions/49879322/can-i-concurrently-write-different-slice-elements
7+ package main
8+
9+ import (
10+ "flag"
11+ "fmt"
12+ "strconv"
13+ "sync"
14+ )
15+
16+ type data struct {
17+ value string
18+ }
19+
20+ func (me data ) String () string {
21+ return me .value
22+ }
23+
24+ func main () {
25+ var (
26+ verbose = flag .Bool ("verbose" , false , "verbose output" )
27+ )
28+ flag .Parse ()
29+
30+ var (
31+ mu = sync.Mutex {}
32+ src = make ([]data , 100 )
33+ dst = make ([]data , 0 )
34+ )
35+
36+ for i := 0 ; i < len (src ); i ++ {
37+ src [i ].value = strconv .Itoa (i )
38+ }
39+
40+ wg := sync.WaitGroup {}
41+ for _ , v := range src {
42+ wg .Add (1 )
43+ go func (v data ) {
44+ defer wg .Done ()
45+
46+ var tmp data
47+ tmp .value = v .value
48+
49+ mu .Lock ()
50+ dst = append (dst , tmp )
51+ mu .Unlock ()
52+ }(v )
53+ }
54+
55+ wg .Wait ()
56+
57+ fmt .Printf ("src-len=%d\t dst-len=%d\n " , len (src ), len (dst ))
58+
59+ if * verbose {
60+ fmt .Println ("=========== SRC ===========" )
61+ for _ , v := range src {
62+ fmt .Println (v )
63+ }
64+ fmt .Println ("=========== DST ===========" )
65+ for _ , v := range dst {
66+ fmt .Println (v )
67+ }
68+ }
69+ }
Original file line number Diff line number Diff line change 1+ // スライス操作 (スライスヘッダの書き換え)はスレッドセーフでは無いというのを示すサンプルです。
2+ // 本サンプルはデータ競合が発生しません。
3+ //
4+ // REFERENCES:
5+ // - https://stackoverflow.com/questions/44152988/append-not-thread-safe
6+ // - https://stackoverflow.com/questions/49879322/can-i-concurrently-write-different-slice-elements
7+ package main
8+
9+ import (
10+ "flag"
11+ "fmt"
12+ "strconv"
13+ "sync"
14+ )
15+
16+ type data struct {
17+ value string
18+ }
19+
20+ func (me data ) String () string {
21+ return me .value
22+ }
23+
24+ func main () {
25+ var (
26+ verbose = flag .Bool ("verbose" , false , "verbose output" )
27+ )
28+ flag .Parse ()
29+
30+ var (
31+ src = make ([]data , 100 )
32+ dst = make ([]data , len (src ))
33+ )
34+
35+ for i := 0 ; i < len (src ); i ++ {
36+ src [i ].value = strconv .Itoa (i )
37+ }
38+
39+ wg := sync.WaitGroup {}
40+ for i , v := range src {
41+ wg .Add (1 )
42+ go func (i int , v data ) {
43+ defer wg .Done ()
44+
45+ var tmp data
46+ tmp .value = v .value
47+
48+ dst [i ] = tmp
49+ }(i , v )
50+ }
51+
52+ wg .Wait ()
53+
54+ fmt .Printf ("src-len=%d\t dst-len=%d\n " , len (src ), len (dst ))
55+
56+ if * verbose {
57+ fmt .Println ("=========== SRC ===========" )
58+ for _ , v := range src {
59+ fmt .Println (v )
60+ }
61+ fmt .Println ("=========== DST ===========" )
62+ for _ , v := range dst {
63+ fmt .Println (v )
64+ }
65+ }
66+ }
Original file line number Diff line number Diff line change 1+ // スライス操作 (スライスヘッダの書き換え)はスレッドセーフでは無いというのを示すサンプルです。
2+ // 本サンプルはデータ競合が発生しています。
3+ //
4+ // REFERENCES:
5+ // - https://stackoverflow.com/questions/44152988/append-not-thread-safe
6+ // - https://stackoverflow.com/questions/49879322/can-i-concurrently-write-different-slice-elements
7+ package main
8+
9+ import (
10+ "flag"
11+ "fmt"
12+ "strconv"
13+ "sync"
14+ )
15+
16+ type data struct {
17+ value string
18+ }
19+
20+ func (me data ) String () string {
21+ return me .value
22+ }
23+
24+ func main () {
25+ var (
26+ verbose = flag .Bool ("verbose" , false , "verbose output" )
27+ )
28+ flag .Parse ()
29+
30+ var (
31+ src = make ([]data , 100 )
32+ dst = make ([]data , 0 )
33+ )
34+
35+ for i := 0 ; i < len (src ); i ++ {
36+ src [i ].value = strconv .Itoa (i )
37+ }
38+
39+ wg := sync.WaitGroup {}
40+ for _ , v := range src {
41+ wg .Add (1 )
42+ go func (v data ) {
43+ defer wg .Done ()
44+
45+ var tmp data
46+ tmp .value = v .value
47+
48+ dst = append (dst , tmp )
49+ }(v )
50+ }
51+
52+ wg .Wait ()
53+
54+ fmt .Printf ("src-len=%d\t dst-len=%d\n " , len (src ), len (dst ))
55+
56+ if * verbose {
57+ fmt .Println ("=========== SRC ===========" )
58+ for _ , v := range src {
59+ fmt .Println (v )
60+ }
61+ fmt .Println ("=========== DST ===========" )
62+ for _ , v := range dst {
63+ fmt .Println (v )
64+ }
65+ }
66+ }
You can’t perform that action at this time.
0 commit comments