首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >高钢生产者消费者

高钢生产者消费者
EN

Stack Overflow用户
提问于 2015-04-14 18:18:57
回答 2查看 10.3K关注 0票数 5

尝试运行以下代码(生产者和消费者)来理解golang中的goroutines和通道(从下面的代码片段删除包和导入):

代码语言:javascript
运行
复制
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

下面是我运行代码时的输出

代码语言:javascript
运行
复制
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

根据我对goroutines和通道的理解:当我们使用go关键字调用产()和从main()消费()时,go运行时启动了2个goroutines(在java世界中类似于线程,而不是实际的OS线程),而main() goroutine来了并停止了“<-go”。现在循环从0到9,在循环中msgs通道一次接收int (0到9) 1,这些int(0到9)1由inside ()并行使用;但是produce不知道它,它只是在0到9之间循环。

问题:假设我的上述理解是正确的。一旦完成了for循环,为什么printLine ()中的下一个没有被打印,以及为什么msgs通道没有关闭?为什么在产品()内停下来,直到消费者吃完所有的味精?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-14 18:44:29

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

如果您只是在示例中再添加几个print语句,很容易看出

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

代码语言:javascript
运行
复制
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)

    }
}

输出:

代码语言:javascript
运行
复制
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
票数 8
EN

Stack Overflow用户

发布于 2021-06-29 13:06:19

代码语言:javascript
运行
复制
package main

import (
    "fmt"
)

var ch chan int
var ch1 chan struct{}

func main() {
    ch = make(chan int)
    ch1 = make(chan struct{})
    go producer()
    go consumer()
    <-ch1
    close(ch)
    close(ch1)
}

func consumer() {
    for {
        fmt.Println("number", <-ch)
    }
}
func producer() {
    for i := 0; i < 10; i++ {
        ch <- i
    }
    ch1 <- struct{}{}
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29634649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档