在go 里,多线程对共享数据的操作一般要使用Mutex 或 Channel 来加锁或隔离通信。下面是一个使用Mutex 和 Channel 比较的例子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
var m map[string]string
type Data struct {
Key string
Value string
}
func worker(queue chan Data, finished chan struct{}) {
for {
d, more := <-queue
if !more {
fmt.Println("Stopping worker due to closed channel")
break
}
//fmt.Print(".")
m[d.Key] = d.Value
}
finished <- struct{}{}
}
func main() {
ConcurrentSender := 100
m = make(map[string]string)
done := []chan struct{}{}
mutex := sync.Mutex{}
start := time.Now()
for i := 0; i < ConcurrentSender; i++ {
d := make(chan struct{})
done = append(done, d)
go func(done chan struct{}, mut *sync.Mutex, ind int) {
for j := 0; j < 100; j++ {
mut.Lock()
m[strconv.Itoa(j)] = strconv.Itoa(j + (1000 * (ind + 1)))
mut.Unlock()
}
done <- struct{}{}
}(d, &mutex, i)
}
for _, d := range done {
_ = <-d
}
duration := time.Since(start)
fmt.Printf("\nMutex Solution took %s", duration)
m = make(map[string]string)
done = []chan struct{}{}
queue := make(chan Data)
// start of the worker go routine
finished := make(chan struct{})
go worker(queue, finished)
start = time.Now()
for i := 0; i < ConcurrentSender; i++ {
d := make(chan struct{})
done = append(done, d)
go func(queue chan Data, done chan struct{}, ind int) {
for i := 0; i < 100; i++ {
// Write element to queue
queue <- Data{Key: strconv.Itoa(i), Value: strconv.Itoa(i + (100 * (ind + 1)))}
}
done <- struct{}{}
}(queue, d, i)
}
for _, d := range done {
_ = <-d
}
duration = time.Since(start)
close(queue)
_ = <-finished
fmt.Printf("Channel Solution took %s", duration)
}
从复杂度和开销来说 Channel
要比 Mutex
昂贵。虽然官方说:
"Don't communicate by sharing memory; instead, share memory by communicating." (“不要通过共享内存进行通信,而是通过通信共享内存。”)
但实际要看场合,简单的、要求实时性比较高的还是使用 Mutex
方便。
本文网址: https://golangnote.com/topic/229.html 转摘请注明来源