GolangNote

Golang笔记

golang共享数据用Mutex 或 Channel

Permalink

在go 里,多线程对共享数据的操作一般要使用Mutex 或 Channel 来加锁或隔离通信。下面是一个使用Mutex 和 Channel 比较的例子。

Go: 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 转摘请注明来源

Related articles

Golang Range 的性能提升Tip

Go 语言里使用 range 可以方便遍历数组(array)、切片(slice)、字典(map)和信道(chan)。这里主要关注他们的性能。...

Write a Comment to "golang共享数据用Mutex 或 Channel"

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.22.3 Processed in 0ms