与n goroutines沟通

时间:2017-11-22 00:23:35

标签: go concurrency

我正在尝试使用通过通道进行通信的n goroutines在golang中实现fibonacci递归。

我从函数返回一个整数,但实际上我只是在通道c上发送f(n-1)+ f(n-2)之和,但这不能正常工作。它打印前两个值正确,后面的每个值只有1.

package main

import "fmt"

// Fibonacci in a recursive version
func fiboR(n int, c chan int ) int {

  if(n == 0){
      c <- 0
      return 0
  } else if n == 1 {
      c <- 1
      return 1
  } else{
      c <- fiboR(n-1,c) + fiboR(n-2,c)
      return fiboR(n-1,c) + fiboR(n-2,c)
  }

}


func main() {
  for i := 0; i < 10; i++ {
    procchan := make(chan int)
    go fiboR(i,procchan)
    fmt.Println(i,<-procchan )
}
}

还可以使用通道接收两个递归调用吗?

2 个答案:

答案 0 :(得分:2)

当您增加i的值时,您的解决方案将尝试输出超过您从频道中提取的值。 您的代码将尝试发送给每个i的频道:

0: 0
1: 1
2: 1,0,1
3: 1,0,1,1,2
4: 1,0,1,1,2,1,0,1,3
...

由于您为每个i创建一个新频道,然后只提取一个值,您将始终获得上面一行中的第一个值。

如果您尝试使用这些修改运行它,它将输出您想要的内容(https://play.golang.org/p/_mn3l5x8iZ)。

package main

import "fmt"

// Fibonacci in a recursive version
func fiboRchan(n int, c chan int) {
    c <- fiboR(n)
}

func fiboR(n int) int {

    if n == 0 {
        return 0
    } else if n == 1 {
        return 1
    } else {
        return fiboR(n-1) + fiboR(n-2)
    }

}

func main() {

    for i := 0; i < 10; i++ {
        procchan := make(chan int)
        go fiboRchan(i, procchan)
        fmt.Println(i, <-procchan)
    }

}

答案 1 :(得分:1)

添加到@nissefors的答案,主要过程很可能是顺序的,因为在for循环中,您将等待通道返回,然后继续下一次迭代。

主函数的微小修改可以立即触发所有的fibonaccis然后在一个单独的for循环中可以访问对应于每个go例程的通道

游乐场网址:https://play.golang.org/p/7e3JnWeSp6

package main

import "fmt"

// Fibonacci in a recursive version
func fiboRchan(n int, c chan int) {
        fmt.Println("PROCESSING FOR %d", n)
    c <- fiboR(n)
}

func fiboR(n int) int {
    if n == 0 {
        return 0
    } else if n == 1 {
        return 1
    } else {
        return fiboR(n-1) + fiboR(n-2)
    }

}

func main() {
    var arr[10]chan int
    for i := 0; i < 10; i++ {
        procchan := make(chan int)
        arr[i] = procchan
        go fiboRchan(i, procchan)
    }
    // By now all the go routines are fired

    // Now iterate through the channel array and read from the
    // respective channel
    for i:=0; i< 10; i++ {
        fmt.Println(i, <-arr[i])
    }

}