You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无缓冲done channel相关Go代码未等待5秒便立即执行?

问题分析与解答

你的误解在于混淆了goroutine的执行时机和程序整体退出的时机,我们一步步拆解代码的执行流程:

  1. 当main函数中执行go worker(done)时,worker这个goroutine会被立刻调度执行,它不会等待main协程的后续代码,所以会马上打印出working...done。
  2. 打印完成后,worker执行done <- true,因为这是无缓冲通道,此时还没有接收方准备好,所以worker会在这里阻塞。
  3. 同时,main协程开始执行time.Sleep(5 * time.Second),进入5秒的睡眠状态,这期间程序不会做任何接收通道的操作。
  4. 5秒睡眠结束后,main执行<-done,此时通道的发送方(worker)和接收方(main)都就绪,worker的阻塞被解除,随后worker退出,main也完成接收并退出程序。

所以实际运行时,打印内容会立刻出现,但程序整体确实会等待5秒后才终止——你预期的“等待5秒后才完成执行”其实是程序退出的时机,而worker的打印操作是独立的goroutine行为,会被立即执行。

如果想要让打印操作在5秒后才执行,你需要把睡眠逻辑放到worker里,或者用通道来控制worker的启动时机,比如:

package main
    
import (
    "fmt"
    "time"
)

func worker(done chan bool, start chan struct{}) {
    <-start // 等待启动信号
    fmt.Print("working...")
    fmt.Println("done")
    done <- true
}

func main() {
    done := make(chan bool)
    start := make(chan struct{})
    
    go worker(done, start)

    time.Sleep(5 * time.Second)
    close(start) // 发送启动信号
    <-done
}

内容的提问来源于stack exchange,提问作者Adarsh Shahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:56:11