关于为什么在getour concurency tutorial

时间:2018-05-29 16:38:14

标签: go

我在游览之旅中无法理解goroutines和频道的使用。参考以下代码:

" 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和&#39; go&#39;运行sum函数。在他们面前的关键字,但他们所做的只是将值发送到渠道。他们不应该与惯例一起运行。但是,当删除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,可能会有所了解。

谢谢,

1 个答案:

答案 0 :(得分:1)

其他人已经在评论中指出,就示例而言,你显然不需要用频道编写这个程序。

从你的问题来看,听起来你好奇为什么需要单独的goroutine 以便程序运行

要回答这个问题,考虑一下在一个只考虑线程的世界中它是如何工作的可能会有所帮助。你有你的主线程,该线程调用sum(s[:len(s)/2], c)。所以现在主线程进入c <- sum中的sum行,并且它会阻塞,因为通道是 unbuffered - 这意味着必须有另一个侦听线程来“取”该通道,以便我们的主线程放入其中。换句话说,线程直接将消息传递给彼此,但是没有第二个线程要传递给它们。死锁!

在这种情况下,goroutines和线程在功能上是等价的。所以没有第二个goroutine,你已经得到了主要的goroutine呼叫......但没有人在另一端拿起电话。