Skip to content

交替打印奇偶数 ​

难度:⭐⭐ 中等 ​

考点 ​

  • 两个 goroutine 交替执行
  • channel 作为同步信号
  • 无缓冲 channel 的阻塞特性

题目描述 ​

使用两个 goroutine 交替打印 1~n 的数字,一个打印奇数,一个打印偶数,保证输出有序。

要求:

  1. PrintOddEven(n) 返回按序排列的 []int
  2. 必须使用两个 goroutine 协作完成,不能在单个 goroutine 中完成
  3. 奇数 goroutine 负责 1, 3, 5...,偶数 goroutine 负责 2, 4, 6...

函数签名 ​

go
func PrintOddEven(n int) []int

提示 ​

  1. 用两个 channel 交替通知对方"轮到你了"
  2. 奇数 goroutine 完成后通知偶数 goroutine,反之亦然
  3. 收集结果可以用一个共享的 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
}

持续学习,持续构建。