侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

使用无缓冲通道实现两个goroutine交替打印数字和字母

2025-12-12 / 0 评论 / 4 阅读

题目

使用无缓冲通道实现两个goroutine交替打印数字和字母

信息

  • 类型:问答
  • 难度:⭐

考点

goroutine创建,channel同步,无缓冲通道

快速回答

通过两个无缓冲通道实现goroutine同步:

  • 创建两个无缓冲通道 numChanletterChan
  • 启动数字打印goroutine:发送数字→接收字母通道信号
  • 启动字母打印goroutine:接收数字通道信号→发送字母
  • 主goroutine初始化信号触发流程
## 解析

原理说明

无缓冲通道的特性是发送和接收操作会阻塞,直到另一方准备好。利用这一特性:

  • 通道A控制数字打印goroutine的执行
  • 通道B控制字母打印goroutine的执行
  • 两个goroutine通过互相发送信号实现严格交替

代码示例

package main

import "fmt"

func main() {
    numChan := make(chan struct{})   // 控制数字打印
    letterChan := make(chan struct{}) // 控制字母打印

    // 数字打印goroutine
    go func() {
        for i := 1; i <= 26; i++ {
            <-numChan  // 等待信号
            fmt.Print(i, " ")
            letterChan <- struct{}{} // 通知字母goroutine
        }
    }()

    // 字母打印goroutine
    go func() {
        for c := 'A'; c <= 'Z'; c++ {
            <-letterChan  // 等待信号
            fmt.Print(string(c), " ")
            numChan <- struct{}{} // 通知数字goroutine
        }
    }()

    // 初始化:触发数字goroutine开始
    numChan <- struct{}{}

    // 防止主goroutine退出
    var input string
    fmt.Scanln(&input)
}

最佳实践

  • 使用struct{}{}作为信号,节省内存(空结构体大小为0)
  • 明确通道的发送/接收顺序避免死锁
  • 主goroutine通过fmt.Scanln保持运行(生产环境用sync.WaitGroup

常见错误

  • 死锁:通道操作顺序错误导致相互等待
  • 遗漏初始化信号:未发送第一个触发信号
  • 通道关闭不当:本例不需要关闭通道
  • 未处理主goroutine退出:导致子goroutine未执行完

扩展知识

  • 无缓冲通道本质:同步操作,发送和接收需在不同goroutine配对出现
  • 带缓冲通道:允许暂存数据,但本例需严格交替,不适合使用
  • 其他同步方式:sync.Mutex(复杂场景)、sync.WaitGroup(等待结束)
  • 实际应用场景:生产者-消费者模型、流水线处理、任务调度