【golang】goroutine交替打印
题目:一个goroutine打印0-100,一个goroutine打印a-z,两个goroutine交替打印。
考点:用channel通知另一个goroutine,并且不能出现goroutine阻塞。
核心原理:channel 是同步阻塞的
在没有缓冲的 channel(或容量已满的 channel)中:
发送方(chan <- val)会阻塞,直到有接收方准备好读取。
接收方(<-chan)也会阻塞,直到有发送方发来数据。
这种阻塞机制就可以天然地用于控制两个 goroutine 的执行顺序。
方案一:
两个channel,一个用来控制打印数字,一个用来控制打印字母,goroutine先接收channel再开始打印,如果没有接收到信号就会阻塞,打印完再作为发送方向对方的channel发送信号,并且第二个goroutine打印完就不要再向channel发送信号了,否则会死锁。因为第一个goroutine已经打印完,不会再接收channel,导致goroutine死锁。
func Printnumandstring() {
chNumber := make(chan struct{})
chStr := make(chan struct{})
wg := &sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
i := 0
for i <= 100 {
<-chNumber
for j := 0; j < 4 && i <= 100; j++ {
println(i)
i++
}
chStr <- struct{}{}
}
}()
go func() {
defer wg.Done()
for i := 'a'; i <= 'z'; i++ {
<-chStr
println(string(i))
if i != 'z' {
chNumber <- struct{}{}
}
}
}()
chNumber <- struct{}{}
wg.Wait()
}