【go】一个关于管道的有趣问题

背景是通过channel来传递数据。但是发现增加channel到一定量级的时候,程序输出和预期不一致。具体参见以下代码:

package main

import (

"fmt"

"time"

)

func changeFlow(left, right chan int) {

left <- 1 + <-right

}

func main() {

num := 100000 //调整num参数,观察不同结果

left := make(chan int)

right := make(chan int)

lastChan := right

startTime := time.Now()

for i := 0; i < num; i++ {

left, right = right, make(chan int)

go changeFlow(left, right)

}

right <- 0

result := <-lastChan

fmt.Println("end at :", time.Now(), time.Since(startTime))

fmt.Println(result)

}

通过go run main.go执行程序。
如上,当num<=100000的时候程序输出结果为the value of num。
一旦大于某个量级(可以调整到1,000,000)的时候,程序异常退出,如下图:

【go】一个关于管道的有趣问题

小白求指教。

附上环境参数:
Go Version:go1.4.2 darwin/amd64
MacBook Pro (Retina, 13-inch, Early 2015)
2.7 GHz Intel Core i5
8 GB 1867 MHz DDR3

回答

我这里运行1000000没问题,运行10000000会直接死机。
你这个代码在运行到right<-0之前所有for生成的goroutine 都处于等待状态,num为多少就会生成多少个,1000000个大约时2G左右内存。
内存溢出了啊。
下面这样子,num多少都没问题。

package main

import (

"fmt"

"time"

)

func changeFlow(left, right chan int) {

right <- 1 + <-left

}

func main() {

num := 5000000 //调整num参数,观察不同结果

left := make(chan int, 1)

right := make(chan int, 1)

startTime := time.Now()

right <- 0

for i := 0; i < num; i++ {

left, right = right, make(chan int, 1)

go changeFlow(left, right)

}

result := <-left

fmt.Println("end at :", time.Now(), time.Since(startTime))

fmt.Println(result)

}

以上是 【go】一个关于管道的有趣问题 的全部内容, 来源链接: utcz.com/a/107251.html

回到顶部