Go基础系列:指定goroutine的执行顺序
2023-09-11 14:18:05 时间
Go channel系列:
当关闭一个channel时,会使得这个channel变得可读。通过这个特性,可以实现一个goroutine执行顺序的技巧。
如果一个goroutine A依赖于另一个goroutine B,在goroutine A中首先通过读goroutine B来阻塞自己,直到goroutine B关闭自身之后,goroutine A才会继续运行。这样,goroutine B就先于goroutine A运行。
下面是一个指定goroutine执行顺序的示例,它保证的顺序是A()-->B()-->C()
。
package main
import (
"fmt"
"time"
)
// A首先被a阻塞,A()结束后关闭b,使b可读
func A(a, b chan struct{}) {
<-a
fmt.Println("A()!")
time.Sleep(time.Second)
close(b)
}
// B首先被a阻塞,B()结束后关闭b,使b可读
func B(a, b chan struct{}) {
<-a
fmt.Println("B()!")
close(b)
}
// C首先被a阻塞
func C(a chan struct{}) {
<-a
fmt.Println("C()!")
}
func main() {
x := make(chan struct{})
y := make(chan struct{})
z := make(chan struct{})
go C(z)
go A(x, y)
go C(z)
go B(y, z)
go C(z)
// 关闭x,让x可读
close(x)
time.Sleep(3 * time.Second)
}
上面的示例中:A goroutine被x阻塞,B goroutine被y阻塞,C goroutine被z阻塞。C依赖的z由B关闭,B依赖的y由A关闭。
如此一来,当main goroutine中的x被关闭后,A()从阻塞中释放,继续执行,关闭y,然后B从阻塞中释放,继续执行,关闭z,C得以释放。由于z被关闭后,z仍然可读,所以多次执行C(z)不会出问题。
A()和B()不能多次执行,因为close()不能操作已被关闭的channel。
注意,上面的channel都是struct{}
类型的,整个过程中,x、y、z这3个通道都没有传递数据,而是直接关闭来释放通道,让某些阻塞的goroutine继续执行下去。显然,这里的x、y、z的作用都是"信号通道",用来传递消息。
相关文章
- Go Web --- 搭建服务器
- go语言输入二维数组
- 关于GO语言遇到illegal UTF-8 encoding 随手记录
- Go语言基础之time包
- Go语言基础之流程控制
- Go编程基础(介绍和安装)
- Go netpoll I/O 多路复用构建原生网络模型之源码深度解析
- go网络库cellent实现socket聊天功能
- 【Go语言】【2】Sublime配置GO开发环境
- 【Go语言】【13】再谈GO语言的结构体
- go安装goctl进行Go Dockefile的自动生成
- 【GO】k8s 管理系统项目21[前端部分–Footer和main]
- [Go] go build 减小二进制文件大小的几种方式
- 【Go基础】理解go语言变量
- 【Go应用】go实现rpc通信协议
- 单链表python和go的代码
- Go语言精进自学系列 | 理解Go语言的包导入
- Go语言自学系列 | golang标准库bytes
- Go语言自学系列 | go常用命令
- Go语言自学系列 | go语言切片的遍历
- go聊天室
- go-rabbitmq
- 理解 Go 标准库中的 atomic.Value 类型
- Go语言开发基础----变量
- Go导入不同目录下包报错解决办法
- 理解Go的Goroutine和channel