了解Go编程语言中的并发性

问题描述 投票:1回答:1

我是Go Language的新手,正在努力理解并发性

package main

import "fmt"

func sendValues(myIntChannel chan int) {
    for i := 0; i < 5; i++ {
        myIntChannel <- i //sending value
    }
}

func main() {
    myIntChannel := make(chan int)
    defer close(myIntChannel)
    go sendValues(myIntChannel)

    for value := range myIntChannel {
        fmt.Println(value) //receiving value
    }
}

以上代码在下面给出了结果

0
1
2
3
4
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    /Users/spikki/Desktop/GoLearning/go_channel.go:51 +0x10b

据我了解,延迟功能将在其周围的功能完成后执行。我无法解释。

如果我使用for循环从通道接收值,其工作方式如下。

    for i := 0; i < 5; i++ {
        fmt.Println(<-myIntChannel) //receiving value
    }

谁能帮我理解这个概念。

for-loop go concurrency channel deferred
1个回答
1
投票

仅当从通道接收到所有值并且通道已关闭时,通道上的[for ... range才终止。

在您的示例中,您希望以延迟功能关闭通道,但是仅在main()返回时才运行。但是main()仅在循环结束时返回。这是导致死锁的原因。 for循环等待通道关闭,然后等待for循环。

这就是发送方应该关闭通道(而不是接收方)并立即解决问题的原因:

func sendValues(myIntChannel chan int) {
    for i := 0; i < 5; i++ {
        myIntChannel <- i //sending value
    }
    close(myIntChannel)
}

func main() {
    myIntChannel := make(chan int)
    go sendValues(myIntChannel)

    for value := range myIntChannel {
        fmt.Println(value) //receiving value
    }
}

输出(在Go Playground上尝试):

0
1
2
3
4
© www.soinside.com 2019 - 2024. All rights reserved.