Go 如何知道缓冲通道已满
如何知道缓冲通道已满?我不知道在缓冲通道已满时是否会被阻止,而是选择删除发送到缓冲通道的项目。您可以使用默认设置。如果无法执行任何一种情况,例如发送到完整通道,则语句将执行默认操作:Go 如何知道缓冲通道已满,go,channel,Go,Channel,如何知道缓冲通道已满?我不知道在缓冲通道已满时是否会被阻止,而是选择删除发送到缓冲通道的项目。您可以使用默认设置。如果无法执行任何一种情况,例如发送到完整通道,则语句将执行默认操作: package main import "fmt" func main() { ch := make(chan int, 1) // Fill it up ch <- 1 select { case ch <- 2: // Put 2 in the cha
package main
import "fmt"
func main() {
ch := make(chan int, 1)
// Fill it up
ch <- 1
select {
case ch <- 2: // Put 2 in the channel unless it is full
default:
fmt.Println("Channel full. Discarding value")
}
}
请注意,当您输入if
块时,比较结果可能无效
相反,我选择删除发送到缓冲通道的项目
这就是所谓的“溢出通道”,你会发现安尼修斯的答案在:
元素的:=范围通道输入{
//如果我们不能马上写下来,放下它,继续前进
挑选{
case ch.output我偶然发现的另一个有用的例子是
引自消息来源:
想法很简单:通过一个连接两个缓冲通道
将消息从传入通道转发到
传出通道。当无法在上放置新消息时
传出通道,从传出通道中取出一条消息(即
是缓冲区中最旧的消息),将其丢弃,然后放置新消息
新释放的传出通道中的消息
也请签出…如果频道已满,我使用此代码删除一个项目。对于只有一个发送go例程的频道,它足以确保发送到ch
之后可以正常工作
// Remove one item from chan if full
if len(ch) == cap(ch) {
// Channel was full, but might not be by now
select {
case _ := <-ch:
// Discard one item
default:
// Maybe it was empty already
}
}
// Now we can send to channel
//如果已满,则从chan中删除一项
如果len(ch)=cap(ch){
//频道已满,但现在可能还没有
挑选{
一个很好的答案:溢出的通道,无论是最旧的还是最新的,都会成为工具箱中的重要工具。存在死锁的风险。将任何一个通道更改为溢出通道都可以解决此问题。丢失某些事件并不重要,如果它们是过时的,则可以轻松替换。当然有解决同一死锁问题的其他方法。问题的前提是,您希望避免通道变满。但通道可以同步,因此会阻塞两端,这是CSP思考的一个重要部分。在您更全面地理解同步之前,不要太努力地阻止缓冲区填满。正如作为练习,请尝试仅使用无缓冲通道解决几个问题。然后,您可以看到在之后添加缓冲是如何提高已在工作的系统的性能的。(有时,过多的缓冲甚至可能会降低性能。)但是,如果只想检查缓冲区是否已满,即使缓冲区未满也不向其写入数据,那该怎么办?有没有办法做到这一点?@Tom你可以实际测试len(ch)=cap(ch){…}
其中len(ch)
是通道中的项目数,而cap(ch)
是容量。但是,当您输入if块时,它可能无效。太好了-这是一个完整的答案!感谢您澄清if语句的结果在输入块时可能无效-我将其添加到原始答案中。如果频道已满,并且您的选择点击了默认值
,则可能无效之后满;根据您的使用情况,len(ch)==cap(ch)
也同样有用
for elem := range ch.input {
// if we can't write it immediately, drop it and move on
select {
case ch.output <- elem:
default:
}
}
close(ch.output)
// Remove one item from chan if full
if len(ch) == cap(ch) {
// Channel was full, but might not be by now
select {
case _ := <-ch:
// Discard one item
default:
// Maybe it was empty already
}
}
// Now we can send to channel