Go channel系列:

* channel入门 <https://www.cnblogs.com/f-ck-need-u/p/9986335.html>

* 为select设置超时时间 <https://www.cnblogs.com/f-ck-need-u/p/9994512.html>

* nil channel用法示例 <https://www.cnblogs.com/f-ck-need-u/p/9994508.html>

* 双层channel用法示例 <https://www.cnblogs.com/f-ck-need-u/p/9994496.html>

* 指定goroutine的执行顺序 <https://www.cnblogs.com/f-ck-need-u/p/9994652.html>
当关闭一个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的作用都是"信号通道",用来传递消息。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信