问题描述
使⽤两个goroutine
交替打印序列,⼀个goroutine
打印数字, 另外⼀个goroutine
打印字⺟, 最终效果如下:
12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728
解题思路
就像我们在操作系统中学到的用信号量来控制进程协作一样,我们可以用两个无缓冲的channel
来控制goroutine
的协作。
一个叫做number
的channel
用来通知打印数字的goroutine
。
另一个叫做letter
的channel
用来通知打印字母的goroutine
。
number, letter := make(chan bool), make(chan bool)
复制代码
打印数字的goroutine
内容很简单:先等待number
的管道通知,然后打印数字,最后通知letter
管道。
go func() {
i := 1
for {
<- number
fmt.Printf("%d%d", i, i + 1)
i += 2
letter <- true
}
}()
复制代码
打印字母的goroutine
的内容也是类似,不过需要控制结束条件:
go func() {
str := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
i := 0
for {
<- letter
if i >= utf8.RuneCountInString(str) {
return
}
fmt.Print(str[i : i+2])
i += 2
number <- true
}
}()
复制代码
完整代码
最后,我们加上syn.WaitGroup
来让主协程等待打印协程的工作结束,完整代码如下:
package main
import (
"fmt"
"sync"
"unicode/utf8"
)
func main() {
number, letter := make(chan bool), make(chan bool)
wait := sync.WaitGroup{}
go func() {
i := 1
for {
<- number
fmt.Printf("%d%d", i, i + 1)
i += 2
letter <- true
}
}()
wait.Add(1)
go func(wait *sync.WaitGroup) {
str := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
i := 0
for {
<- letter
if i >= utf8.RuneCountInString(str) {
wait.Done()
return
}
fmt.Print(str[i : i+2])
i += 2
number <- true
}
}(&wait)
number <- true
wait.Wait()
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END