Multithreading 围棋中的多线程。谁能给我解释一下这些答案吗?

Multithreading 围棋中的多线程。谁能给我解释一下这些答案吗?,multithreading,go,concurrency,goroutine,Multithreading,Go,Concurrency,Goroutine,我在模拟考试中有两道题。我得到了答案,但无法理解背后的理由 我将首先发布代码,然后发布问题和答案。也许有人会很乐意向我解释答案 package main import "fmt" func fact(n int, c chan int, d chan int) { k := /* code to compute factorial of n */ z := <- d c <- k + z d <- z + 1 } func mai

我在模拟考试中有两道题。我得到了答案,但无法理解背后的理由

我将首先发布代码,然后发布问题和答案。也许有人会很乐意向我解释答案

package main

import "fmt"

func fact(n int, c chan int, d chan int) {

    k := /* code to compute factorial of n */

    z := <- d

    c <- k + z

    d <- z + 1

}

func main() {

    r := 0

    c := make(chan int)
    d := make(chan int)

    for i = 0 ; i < N ; i++ {
        go fact(i,c,d)
    }

    d <- 0

    for j = 0 ; j < N ; j++ {
        r = r + <-c
    }

    fmt.Printf("result = %d\n",r)

}
主程序包
输入“fmt”
func事实(n int,c chan int,d chan int){
k:=/*计算n的阶乘的代码*/

z:=最好不要将其视为“多线程”。Go提供了直接的并发功能,而不是线程。它碰巧通过线程实现了并发,但这是一个实现细节。有关更深入的讨论,请参阅Rob Pike的演讲

您的问题的关键在于通道默认是同步的(如果它们在构造期间未被缓冲)。当一个goroutine写入通道时,它将阻塞,直到其他goroutine从该通道读取。因此,当此行执行时:

z := <- d
d <- 0
在第(2)步,我们尝试写入
d
。什么允许这样做?从
d
读取另一个goroutine。记住,我们启动了
N
goroutines,所有goroutines都尝试从
d
读取。其中只有一个会成功。其他goroutine将在第(1)步阻塞,等待某个东西出现在
d
上。当第一个到达(2)时会发生这种情况。然后该goroutine退出,一个随机goroutine将继续

但是最终的goroutine将永远无法写入
d
,并且将泄漏。为了解决此问题,需要在最终的
Printf
之前添加以下内容:

<-d

如果我们省略“d”行,程序将如何运行
<-d