Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 当通过通道接收值时,为什么看不到输出_Go_Concurrency - Fatal编程技术网

Go 当通过通道接收值时,为什么看不到输出

Go 当通过通道接收值时,为什么看不到输出,go,concurrency,Go,Concurrency,在下一个示例中,我不明白为什么接收时未打印结束值 package main import "fmt" func main() { start := make(chan int) end := make(chan int) go func() { fmt.Println("Start") fmt.Println(<-start) }() go func() { fmt.Println("End")

在下一个示例中,我不明白为什么接收时未打印结束值

package main

import "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可以解决这个问题

因为程序在到达func main末尾时退出,而不管是否有其他goroutine正在运行。一旦第二个函数从结束通道接收到消息,main在该通道上的发送即被解除阻止,程序完成,在接收到的值有机会传递给Println之前。

未打印结束值,因为一旦主goroutine(主函数实际上是goroutine)完成,其他非主goroutine就没有机会完成

当函数main返回时,程序退出。此外,goroutine是独立的执行单元,当许多goroutine一个接一个地启动时,您不能依赖goroutine实际启动的时间。代码的逻辑必须独立于调用goroutine的顺序

解决你的问题的一个方法,也是最简单的一个方法,就是在你的主要功能的末尾放一个时间

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。

除了必须指定时间的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()
}