开发者社区 问答 正文

goroutine的问题?报错

/*
摘自: 
https://code.google.com/p/go/source/browse/2013/advconc/buffer/buffer.go?repo=talks
*/
package main

import (
	"fmt"
	"time"
)

func main() {
	in, out := make(chan int), make(chan int)
	go buffer(in, out)

	time.Sleep(4 * time.Second) // -> 添加4秒延迟

	for i := 0; i < 10; i++ {
		in <- i
	}
	close(in) // 会造成in为nil吗? 

	for i := range out {
		fmt.Println(i)
	}

}

func buffer(in <-chan int, out chan<- int) {
	var buf []int // 无限制的缓存

	for in != nil || len(buf) > 0 {
		var i int = 0
		var c chan<- int

		if len(buf) > 0 { // 如果缓存中还有数据,则取出发送。
			i = buf[0]
			c = out
		}
		select {
		case c <- i: // 送出左端数据
			buf = buf[1:]
		case n, ok := <-in: // 取出in管道数据,放入缓存中。
			if ok {
				buf = append(buf, n)
			} else {
				in = nil // 关闭in
			}

		}
	}
}
问题一:如果在16行添加4秒延迟后,14行建立goroutine后为何会产生阻塞?从逻辑上,进入到40行的select后43行会阻塞,但41行的向channel写入数据为何阻塞,起码写第一个数据单元应该无阻塞。

问题二:执行为何报错:

展开
收起
爱吃鱼的程序员 2020-06-22 19:09:09 390 分享 版权
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    将23/24行改为fori:=0;i<10;i++{ 

    fmt.Println(<-out)

    则不会报错,为何?

     fori:=rangeout{     range有问题吗?

    差了第52行应该是close(out),就不会出错了。 
    2020-06-22 19:09:25
    赞同 展开评论
问答分类:
问答地址: