golang之slice并发访问

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

slice在并发执行中不会报错, 但数据会丢失, 可以加锁解决; map在高并发执行中会直接报错, 需要加锁使用

package main

import (
 "fmt"
 "sort"
 "time"
)

var s []int

func appendValue(i int) {
 s = append(s, i)
}

func main() {

 for i := 0; i < 10000; i++ {
  go appendValue(i)
 }

 sort.Ints(s) //给切片排序,先排完序再打印,

 for i, v := range s {
  fmt.Println(i, ":", v)

 }

 time.Sleep(5e9)

}

输出为:

0 : 0
1 : 0
2 : 0
3 : 0
4 : 0
5 : 0
6 : 0
7 : 0
8 : 0
9 : 0
10 : 0
11 : 0
12 : 0
13 : 0
14 : 0
15 : 0
16 : 0
17 : 0
18 : 0
19 : 0
20 : 0
21 : 0
22 : 0
23 : 0
24 : 0
25 : 0
26 : 0
27 : 0
28 : 0
29 : 0
30 : 0
31 : 0
32 : 0
33 : 0
34 : 0
35 : 0
36 : 0
37 : 0
38 : 0
39 : 0
40 : 0
41 : 0
42 : 0
43 : 0
44 : 0
45 : 0
46 : 0
47 : 0
48 : 0
49 : 0
50 : 0
51 : 0
52 : 0
53 : 0
54 : 0
55 : 0
56 : 0
57 : 0
58 : 0
59 : 0
60 : 0
61 : 0
62 : 0
63 : 0
64 : 0
65 : 0
66 : 0
67 : 0
68 : 0
69 : 0
70 : 0
71 : 0
72 : 0
73 : 0
74 : 0
75 : 0
76 : 0
77 : 0
78 : 0
79 : 0
80 : 0
81 : 0
82 : 0
83 : 0
84 : 0
85 : 1
86 : 2
87 : 3
88 : 6
89 : 8
90 : 12
91 : 13
92 : 14
93 : 19
94 : 28
95 : 30
96 : 31
97 : 32
98 : 33
99 : 34
100 : 35
101 : 36
102 : 44
103 : 45
104 : 46
105 : 47
106 : 48
107 : 49
108 : 50
109 : 51
110 : 52
111 : 53
112 : 54
113 : 55
114 : 56
115 : 57
116 : 58
117 : 59
118 : 60
119 : 61
120 : 62
121 : 63
122 : 64
123 : 65
124 : 66
125 : 67
126 : 68
127 : 69
128 : 70
129 : 71
130 : 72
131 : 73
132 : 74
133 : 75
134 : 76
135 : 77
136 : 78
137 : 79
138 : 80
139 : 81
140 : 82
141 : 83
142 : 84
143 : 85
144 : 86
145 : 87
146 : 88
147 : 89
148 : 90
149 : 91
150 : 92
151 : 93
152 : 94
153 : 95
154 : 96
155 : 97
156 : 98
157 : 99
158 : 100
159 : 101
160 : 102
161 : 103
162 : 104
163 : 105
164 : 106
165 : 107
166 : 108
167 : 109
168 : 110
169 : 111
...

8309 : 9970
8310 : 9971
8311 : 9972
8312 : 9973
8313 : 9974
8314 : 9976
8315 : 9977
8316 : 9978
8317 : 9979
8318 : 9980
8319 : 9981
8320 : 9982
8321 : 9983
8322 : 9984
8323 : 9985
8324 : 9986
8325 : 9987
8326 : 9988
8327 : 9989
8328 : 9990
8329 : 9991
8330 : 9992
8331 : 9993
8332 : 9995
8333 : 9996
8334 : 9994
8335 : 9997
8336 : 9998
8337 : 9999

没有到 9999 : 9999


加锁之后:


package main

import (
 "fmt"
 "sort"
 "sync"
 "time"
)

var s []int
var lock sync.Mutex

func appendValue(i int) {
 lock.Lock()
 s = append(s, i)
 lock.Unlock()
}

func main() {

 for i := 0; i < 10000; i++ {
  go appendValue(i)
 }

 sort.Ints(s) //给切片排序,先排完序再打印,
 
 for i, v := range s {
  fmt.Println(i, ":", v)

 }

 time.Sleep(5e9)

}


输出为:

0 : 0
1 : 1
2 : 2
3 : 3
4 : 4
5 : 5
6 : 6
7 : 7
8 : 8
9 : 9
10 : 10
11 : 11
12 : 12
13 : 13
14 : 14

...

9992 : 9992
9993 : 9993
9994 : 9994
9995 : 9995
9996 : 9996
9997 : 9997
9998 : 9998
9999 : 9999


参考:

golang并发安全: slice和map并发不安全,及其解决方法




米哈游面试:

package main

import (
 "fmt"
)

func main() {

 var sli []int

 for i := 0; i < 10; i++ {

  go func() {
   //for j := 0; j < 10; j++ {
   sli = append(sli, 1)
   //}
  }()
 }

 //time.Sleep(time.Second)
 fmt.Println(len(sli))

}

这样一般会是0



package main

import (
 "fmt"
)

func main() {

 var sli []int

 for i := 0; i < 10; i++ {

  go func() {
   for j := 0; j < 10; j++ {
    sli = append(sli, 1)
   }
  }()
 }

 //time.Sleep(time.Second)
 fmt.Println(len(sli))

}

这样一般也是0


package main

import (
 "fmt"
 "time"
)

func main() {

 var sli []int

 for i := 0; i < 10; i++ {

  go func() {
   //for j := 0; j < 10; j++ {
   sli = append(sli, 1)
   //}
  }()
 }

 time.Sleep(time.Millisecond)
 fmt.Println(len(sli))

}

这样一般<10


package main

import (
 "fmt"
 "time"
)

func main() {

 var sli []int

 for i := 0; i < 10; i++ {

  go func() {
   for j := 0; j < 10; j++ {
    sli = append(sli, 1)
   }
  }()
 }

 time.Sleep(time.Microsecond)
 fmt.Println(len(sli))

}

一般<100

本文由 mdnice 多平台发布

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: go