Go内存模型2 | Go主题月

534 阅读1分钟

Go通道实现同步

image.png goroutineA 通过获取到通道权限,可以执行代码,执行完后,将通道标识为可通行,gB可以才能获取通道,往下执行代码块。这个在现实业务场景就像,我们在火车上上厕所,一旦厕所里有人,提示灯会展示里面有人,所以我不用在门口等待,可以搞其他事情,比如玩手机等,等提示灯显示空闲,我就过去上厕所。go大佬们实现这种方式的目的为了什么,我猜测是不是为了节省资源考虑,实现AIO这种线程模型?

通道实现有两种方式

1,可以设置缓存

var c = make(chan int, 10)
var a string

func f() {
	a = "hello, world"
	c <- 0
}

func main() {
	go f()
	<-c
	print(a)
}

c里面设置10表示缓存大小为10。

2,不设置缓存

var c = make(chan int)
var a string

func f() {
	a = "hello, world"
	<-c
}

func main() {
	go f()
	c <- 0
	print(a)
}

如果通道没有设置缓存,那就无法本地缓存数据,获取到通道权限的时候,执行完指定代码后,直接给通道发送值0。

缓存通道还有一种用途:

var limit = make(chan int, 3)

func main() {
	for _, w := range work {
		go func(w func()) {
			limit <- 1
			w()
			<-limit
		}(w)
	}
	select{}
}

当设置通道缓存容量为3时,可以表示通道可以同时被三个g获取到,也就是三个g可以同时执行指定代码块。

通道这个概念在我们生活中可以随处可以找到,大佬们的灵感来源于生活,并高于生活。