我在游览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/