繁体   English   中英

Golang并发和单个通道阻塞,需要解释

[英]Golang concurrency and blocking with a single channel, explanation needed

我正在玩https://tour.golang.org/concurrency/5上提供的代码。 我的想法是,我可以摆脱退出通道来简化代码,并且仍然保持正确的程序行为-仅出于学习目的。

这是我得到的代码(为了获得更好的可读性,对其进行了进一步简化):

package main

import "fmt"
import "time"

func sendNumbers(c chan int) {  
    for i := 0; i < 2; i++ {
        c <- i
    }
}

func main() {
    c := make(chan int)
    go func() {
        for i := 0; i < 2; i++ {
            fmt.Println(<-c)
        }
    }()
    time.Sleep(0 * time.Second)
    sendNumbers(c)
}

在此代码中,我产生的go例程应该能够在返回之前接收2个数字。 我接下来调用的sendNumbers()函数将恰好2个数字发送到通道c。

因此,该程序的预期输出为2行:0和1。但是,当我在页面上运行代码时,我得到的只是包含0的一行。

注意

time.Sleep(0 * time.Second) 

尽管我是在调用sendNumbers(c)之前故意添加的。 如果我将其更改为

time.Sleep(1 * time.Second) 

输出变为预期:

0
1

所以,我对发生的事情感到困惑。 有人可以解释发生了什么吗? 无论在调用sendNumbers()之前经过了多长时间,发送和接收块都不应同时发送吗?

在Go中,无论其他goroutine是否仍在运行,只要主函数返回,程序都会立即退出。 如果要确保main函数不会过早退出,则需要某种同步机制。 https://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/
您不必绝对必须使用同步原语,也可以只使用通道来完成,可以说是一种更惯用的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM