gpt4 book ai didi

go - 即使没有竞争条件也没有得到任何输出

转载 作者:行者123 更新时间:2023-12-02 18:16:05 25 4
gpt4 key购买 nike

我正在尝试使用缓冲 channel 在 Golang 中创建生产者-消费者消息队列系统。这是我的实现。

package main

import "fmt"

type MessageQueue struct {
storage chan int
count int
}

var done = make(chan bool)

func NewMessageQueue(count int) *MessageQueue {
ret := &MessageQueue{
count: count,
storage: make(chan int, count),
}
return ret
}

func (m *MessageQueue) Produce() {
for i := 0; i < m.count; i++ {
m.storage <- i + 1
}
done <- true
}

func (m *MessageQueue) Consume(f func(int) int) {
for each := range m.storage {
fmt.Printf("%d ", f(each))
}
}

func main() {
op1 := func(a int) int {
return a * a
}
msq := NewMessageQueue(10)
go msq.Produce()
go msq.Consume(op1)
<-done
}

但不幸的是,当我运行 go run main.go 时,我无法获得输出,但是当我尝试 go run - 时检查是否存在任何竞争条件 - race main.go,我确实得到了输出。我无法理解为什么会发生这种情况。有人可以帮我吗?

最佳答案

当您的生产者可以发送值时,它会在 done channel 上发送一个值,以便您的应用可以立即终止。

相反,当生产者完成时,它应该关闭 m.storage channel ,表示不再发送任何值,并且在 done 上不发送值,因为你还没有完成!

当值被消耗时,您就完成了,因此在 Consume() 中的 done 上发送一个值:

func (m *MessageQueue) Produce() {
for i := 0; i < m.count; i++ {
m.storage <- i + 1
}
close(m.storage)
}

func (m *MessageQueue) Consume(f func(int) int) {
for each := range m.storage {
fmt.Printf("%d ", f(each))
}
done <- true
}

这将输出(在 Go Playground 上尝试):

1 4 9 16 25 36 49 64 81 100 

需要 done channel ,因为消费不会在 main goroutine 中发生,并且 main goroutine 必须等待它结束。

如果您在 main goroutine 上进行消费,则可以删除 done channel :

msq := NewMessageQueue(10)
go msq.Produce()
msq.Consume(op1)

Go Playground 上试试这个.

关于go - 即使没有竞争条件也没有得到任何输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71569119/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com