go - 在golang中,生产者消费者

  显示原文与译文双语对照的内容

尝试运行下面的代码( 。生产者&使用者) 以了解 golang ( 从下面的代码段中删除了包和导入) 中的goroutine和通道:


var done = make(chan bool)
var msgs = make(chan int)

func produce() {
 for i := 0; i <10; i++ {
 msgs <- i
 }
 fmt.Println("Before closing channel")
 close(msgs)
 fmt.Println("Before passing true to done")
 done <- true
}

func consume() {
 for {
 msg := <-msgs
 time.Sleep(100 * time.Millisecond)
 fmt.Println("Consumer:", msg)
 }
}

func main() {
 go produce()
 go consume()
 <-done
 fmt.Println("After calling DONE")
}

源代码:http://www.golangpatterns.info/concurrency/producer-consumer

下面是运行代码时的输出


Consumer: 0
Consumer: 1
Consumer: 2
Consumer: 3
Consumer: 4
Consumer: 5
Consumer: 6
Consumer: 7
Consumer: 8
Before closing channel
Before passing true to done
After calling DONE

根据我对goroutine和频道的理解: 使用go关键字从 main() 调用 produce() 和 consume() 时,运行时启动 2 goroutine ( 。java世界中的线程类型,但不是实际的操作系统线程),main() goroutine在" <-done"处停止。 now inside循环goes在loop循环接收int通道接收 int ( 0至 9 ) 1 time但产生 int produce produce produce produce produce produce 9.

问题:假设我上面的理解正确。 is循环为原因,为什么 produce() 中的下一个is没有打印,而且为什么is通道不会被关闭。 为什么goroutine在 produce() 内部停止,直到消费者消耗所有的消息?

时间: 原作者:

msgs 通道没有缓冲。 这意味着发送完成时,必须有一个可以完成的对应接收操作。 这提供了goroutine之间的同步点。

如果你只向示例添加几个打印语句,就很容易看到

http://play.golang.org/p/diYQGN-iwE


func produce() {
 for i := 0; i <4; i++ {
 fmt.Println("sending")
 msgs <- i
 fmt.Println("sent")
 }
 fmt.Println("Before closing channel")
 close(msgs)
 fmt.Println("Before passing true to done")
 done <- true
}

func consume() {
 for msg := range msgs {
 fmt.Println("Consumer:", msg)
 time.Sleep(100 * time.Millisecond)

 }
}

输出:


sending
Consumer: 0
sent
sending
Consumer: 1
sent
sending
Consumer: 2
sent
sending
Consumer: 3
sent
Before closing channel
Before passing true to done
After calling DONE

原作者:
...