高朗的生产者消费者

sro*_*ock 3 go goroutine

尝试运行以下代码(生产者和使用者)以了解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")
}
Run Code Online (Sandbox Code Playgroud)

源代码来自: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
Run Code Online (Sandbox Code Playgroud)

根据我对goroutines和channel的理解:当我们使用go关键字从main()调用produce()和consume()时,将运行两个goroutines(Java世界中的某种线程,但不是实际的OS线程)和main ()goroutine在“ <-完成”处停止。现在在Produce()内部-循环从0到9,在循环内部,msgs通道一次接收由int()并行消耗的int(0至9)1;但是Produce对此一无所知,只是不断循环0到9。

问题:假设我的理解是正确的。一次,fo​​r循环完成了,为什么Produce()中的下一个printLine无法打印,以及为什么msgs通道没有关闭?为什么goroutine在Producer()内部停止,直到消费者耗尽了所有msg?

Jim*_*imB 6

msgs信道是无缓冲。这意味着要完成发送,必须有一个相应的接收操作也可以完成。这在goroutines之间提供了一个同步点。

很容易看出您是否仅在示例中添加了一些打印语句

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)

    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)