为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在通过通道接收值时看不到输出

为什么在通过通道接收值时看不到输出

Go
LEATH 2022-01-04 21:08:12
在下一个例子中,我不明白为什么收到时没有打印最终值package mainimport "fmt"func main() {    start := make(chan int)    end := make(chan int)    go func() {        fmt.Println("Start")        fmt.Println(<-start)    }()    go func() {        fmt.Println("End")        fmt.Println(<-end)    }()    start <- 1    end <- 2}我知道 sync.WaitGroup 可以解决这个问题。
查看完整描述

3 回答

?
狐的传说

TA贡献1804条经验 获得超3个赞

因为程序在到达 结束时退出func main,无论是否有其他 goroutine 正在运行。一旦第二个函数从end通道接收到, main 在该通道上的发送就会被解除阻塞并且程序完成,然后接收到的值有机会被传递给Println


查看完整回答
反对 回复 2022-01-04
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

除了必须指定时间的 sleep 之外,您还可以使用 waitgroup 使您的程序等待 goroutine 完成执行。


package main


import "fmt"

import "sync"


var wg sync.WaitGroup


func main() {

    start := make(chan int)

    end := make(chan int)


    wg.Add(2)

    go func() {

        defer wg.Done()

        fmt.Println("Start")

        fmt.Println(<-start)

    }()


    go func() {

        defer wg.Done()

        fmt.Println("End")

        fmt.Println(<-end)

    }()


    start <- 1

    end <- 2

    wg.Wait()

}


查看完整回答
反对 回复 2022-01-04
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

最终值不会被打印出来,因为一旦maingoroutine(该main函数实际上是一个 goroutine)完成(换句话说,被解除阻塞)其他非主 goroutines 就没有机会完成。


当函数 main() 返回时,程序退出。此外,goroutines 是独立的执行单元,当它们中的一些一个接一个启动时,你不能依赖 goroutine 何时实际启动。您的代码逻辑必须独立于调用 goroutine 的顺序。


解决您的问题的一种方法(在您的情况下是最简单的方法)是将 atime.Sleep放在main()函数的末尾。


time.Sleep(1e9)

这将保证主 goroutine 不会解除阻塞,并且其他 goroutine 将有更改以执行。


package main


import (

    "fmt"

    "time"

)


func main() {

    start := make(chan int)

    end := make(chan int)


    go func() {

        fmt.Println("Start")

        fmt.Println(<-start)

    }()


    go func() {

        fmt.Println("End")

        fmt.Println(<-end)

    }()


    start <- 1

    end <- 2


    time.Sleep(1e9)

}

您提到的另一个解决方案是使用waitgroup.


查看完整回答
反对 回复 2022-01-04
  • 3 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信