Golang笔记

golang共享数据用Mutex 或 Channel

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

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 (转载注明出处)
关于GolangNote:记录在工作中使用golang 遇到、面临的相关问题及解决方法。如果你在这里获得一些知识或信息,解决你的编程问题,请考虑捐赠给不幸的人或者你喜欢的慈善机构,除捐赠外,种植树木、志愿服务或减少排碳的行为也很有益处。如果你有任何问题可以在下面 留言
Be the first to comment!
Captcha image
Relative Articles