内容简介:当关闭一个channel时,会使得这个channel变得可读。通过这个特性,可以实现一个goroutine执行顺序的技巧。如果一个goroutine A依赖于另一个goroutine B,在goroutine A中首先通过读goroutine B来阻塞自己,直到goroutine B关闭自身之后,goroutine A才会继续运行。这样,goroutine B就先于goroutine A运行。下面是一个指定goroutine执行顺序的示例,它保证的顺序是
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的作用都是"信号通道",用来传递消息。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- c# – “SMTP主机未指定” – 但是是否指定?
- 运维安全 | 如何限制指定账户不能SSH只能SFTP在指定目录
- ViewGroup 默认顺序绘制子 View,如何修改?什么场景需要修改绘制顺序?
- Zabbix监控指定端口
- Android指定专用APN
- iOS 指定初始化方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Mechanics of Web Handling
David R. Roisum
This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!