读取Go通道的块

huangapple go评论76阅读模式
英文:

Reading Go channels in chunks

问题

我是新手学习Go语言,我正在尝试编写一个程序,其中包含两种类型的goroutine,一些goroutine将向通道写入数据,另一些goroutine将从该通道读取数据。

我希望设置这样的机制,使得从通道读取数据的goroutine每次读取两个元素,而写入数据的goroutine每次只写入一个元素。类似于以下代码:

n := 20
ch := make(chan struct{}, 2)

// 写入数据的goroutine
for i := 0; i < n*2; i++ {
    go func() {
        ch <- struct{}{}
    }()
}

// 读取数据的goroutine
for i := 0; i < n; i++ {
    go func() {
        <- ch
        <- ch
    }()
}

我希望我的写入数据的goroutine在通道满时继续添加元素,然后让其中一个读取数据的goroutine一次性处理通道中的两个元素并清空通道。基本上,读取数据的goroutine必须等待通道满时才能清空通道。

不用说,我上面的实现会有竞态条件,并且不是解决这个问题的最佳方法。我该如何解决这个问题?我不确定如何使我的读取数据的goroutine一次读取多个元素并避免竞态条件。我可以尝试使用Go的其他特性来解决这个问题,而不仅仅是通道。

英文:

I'm new to Go, and I'm trying to write a program that has two types of goroutines, some that will write to a channel and some that will read from that channel.

I want to set it up so that the goroutines that read from the channel will read in chunks of two, while the writer goroutines will write one by one. Something like this:

n := 20
ch := make(chan struct{}, 2)

// writer goroutines
for i := 0; i &lt; n*2; i++ {
    go func() {
        ch &lt;- struct{}{}
    }()
}

// reader goroutines
for i := 0; i &lt; n; i++ {
    go func() {
        &lt;- ch
        &lt;- ch
    }()
}

I want my writer goroutines to keep adding elements to my channel until it's full, after which I want one of my reader goroutines to process both elements in the channel and clear it all at once. Basically the reader goroutines must wait for the channel to be full to clear it.

Needless to say my implementation above will have race conditions and is not the best way to go about it. How can I solve this issue? I'm not sure how I can make my reader goroutines read multiple things at a time and avoid race issues at the same time. I'm open to using other features of Go instead of channels.

答案1

得分: 1

len(ch) - 将返回通道缓冲区中排队(未读)的元素数量。您可以使用此函数确保在消费之前通道已满。

另外,您需要确保主程序在读取器和写入器 goroutine 完成之前等待。您可以使用 sync.WaitGroup 来实现这一点。

参考:sync.WaitGroup 示例

英文:

len(ch) - will return the number of elements queued (unread) in the channel buffer. You can use this function to make sure the channel is full before consuming.

On another note, you have to make your main routine wait till both reader and writer goroutines are complete. you can do this using sync.WaitGroup

reference : sync.WaitGroup example

huangapple
  • 本文由 发表于 2022年2月14日 22:28:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/71113472.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定