交替打印奇偶数
难度:⭐⭐ 中等
考点
- 两个 goroutine 交替执行
- channel 作为同步信号
- 无缓冲 channel 的阻塞特性
题目描述
使用两个 goroutine 交替打印 1~n 的数字,一个打印奇数,一个打印偶数,保证输出有序。
要求:
PrintOddEven(n)返回按序排列的 []int- 必须使用两个 goroutine 协作完成,不能在单个 goroutine 中完成
- 奇数 goroutine 负责 1, 3, 5...,偶数 goroutine 负责 2, 4, 6...
函数签名
go
func PrintOddEven(n int) []int提示
- 用两个 channel 交替通知对方"轮到你了"
- 奇数 goroutine 完成后通知偶数 goroutine,反之亦然
- 收集结果可以用一个共享的 channel 或 slice + mutex
参考答案(Go)
点击展开参考答案
go
//go:build ignore
package answer
func PrintOddEven(n int) []int {
if n <= 0 {
return []int{}
}
result := make([]int, 0, n)
ch := make(chan int, n)
oddTurn := make(chan struct{}, 1)
evenTurn := make(chan struct{}, 1)
done := make(chan struct{})
// 奇数 goroutine
go func() {
for i := 1; i <= n; i += 2 {
<-oddTurn
ch <- i
if i+1 <= n {
evenTurn <- struct{}{}
} else {
close(done)
}
}
}()
// 偶数 goroutine
go func() {
for i := 2; i <= n; i += 2 {
<-evenTurn
ch <- i
if i+1 <= n {
oddTurn <- struct{}{}
} else {
close(done)
}
}
}()
// 启动奇数先行
oddTurn <- struct{}{}
<-done
close(ch)
for v := range ch {
result = append(result, v)
}
return result
}