为何无缓冲done channel相关Go代码未等待5秒便立即执行?
问题分析与解答
你的误解在于混淆了goroutine的执行时机和程序整体退出的时机,我们一步步拆解代码的执行流程:
- 当
main函数中执行go worker(done)时,worker这个goroutine会被立刻调度执行,它不会等待main协程的后续代码,所以会马上打印出working...done。 - 打印完成后,
worker执行done <- true,因为这是无缓冲通道,此时还没有接收方准备好,所以worker会在这里阻塞。 - 同时,
main协程开始执行time.Sleep(5 * time.Second),进入5秒的睡眠状态,这期间程序不会做任何接收通道的操作。 - 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
相关产品推荐
相关产品推荐

