使用两个Goroutine,向标准输出中按顺序按顺序交替打出字母与数字,输出是a1b2c3
要实现这个功能,我们需要两个 goroutine 之间的同步。Go 标准库中的
sync
包提供了多种同步原语,比如sync.Mutex
、sync.WaitGroup
以及sync.Cond
等,可以用来进行协程间的同步。然而,在这个特定案例中,使用 channel 来进行同步可能是最简单和最直观的方式。
下面是一个使用 channel 实现的示例代码:
package main
import (
"fmt"
"sync"
)
func main() {
letter, number := make(chan bool), make(chan bool)
wait := sync.WaitGroup{}
go func() {
i := 1
for {
select {
case <-number:
fmt.Print(i)
i++
letter <- true
}
}
}()
wait.Add(1)
go func(wait *sync.WaitGroup) {
for ch := 'a'; ch <= 'z'; ch++ {
select {
case <-letter:
if ch > 'z' {
wait.Done()
return
}
fmt.Printf("%c", ch)
number <- true
}
}
}(&wait)
number <- true // 触发第一次打印
wait.Wait() // 等待字母打印完成
}
在这个程序中,我们定义了两个通道 letter
和 number
来控制执行流程。首先,我们启动数字打印的 goroutine,它会在接收到 number
通道的信号后打印一个数字,并通过 letter
通道发送信号给字母打印的 goroutine。接着,我们启动字母打印的 goroutine,它会在接收到 letter
通道的信号后打印一个字母,并通过 number
通道发送信号回数字打印的 goroutine。最后,我们通过发送信号到 number
通道开始整个交替打印的过程,并使用 sync.WaitGroup
等待字母打印完成。
请注意,这个程序只是作为一个示例,它将无限循环地打印数字和字母。如果你想让程序按照你的输出要求 a1b2c3...z26
运行并且在结束时退出,你需要添加逻辑来停止两个 goroutine。上面的代码已经包含了这样的逻辑:当字母打印到 'z'
时,调用 wait.Done()
来通知主 goroutine 所有打印工作已完成。