我在游览go时难以理解goroutine和通道的使用。从以下引用以下代码:

https://tour.golang.org/concurrency/2

package main

import "fmt"

func sum(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    c <- sum // send sum to c
}

func main() {
    s := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    go sum(s[:len(s)/2], c)
    go sum(s[len(s)/2:], c)
    x, y := <-c, <-c // receive from c

    fmt.Println(x, y, x+y)
}

它使用goroutines前面带有'go'关键字的goroutines运行sum函数,但是它们所做的只是将值发送到通道中。它们不必与go例程一起运行。但是,当删除go关键字以正常运行函数时,出现此错误:
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.sum(0xc420059f10, 0x3, 0x6, 0xc420088060)
    /tmp/compile33.go:10 +0x5a
main.main()
    /tmp/compile33.go:17 +0x99

我不明白为什么这里需要goroutines。我可能会误解这个概念,并且希望对更熟悉go的人有所了解。

谢谢,

最佳答案

其他人已经在评论中指出,作为示例,您显然不需要编写带有通道的程序。

但是,从您的问题看来,您似乎很好奇为什么需要单独的goroutines才能运行程序。

要回答这个问题,考虑一下在您只考虑线程的世界中如何工作可能会有所帮助。您已经有了主线程,并且该线程调用sum(s[:len(s)/2], c)。因此,现在主线程到达c <- sum中的sum行,并且阻塞了,因为该通道是未缓冲的-这意味着必须有另一个监听线程从该通道“获取”,以便我们的主线程将某些东西放入其中。换句话说,线程之间直接传递消息,但是没有第二个线程可以传递。僵局!

在这种情况下,goroutine和线程在功能上是等效的。因此,没有第二个goroutine,您就可以调用主goroutine了……但是没有人在另一端接听电话。

关于go - 在GoTour并发教程中为何需要Goroutines的解释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50589143/

10-16 12:28