如何知道缓冲通道已满?我不知道在缓冲通道满时被阻塞,而是选择丢弃发送到缓冲通道的项目。Golang - 如何知道缓冲通道已满
回答
您可以将select
statement设为默认值。如果它是不可能做任何的情况下,如发送到一个完整的通道,该语句将做默认:
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")
}
}
输出:
通道全。丢弃值
游乐场:http://play.golang.org/p/1QOLbj2Kz2
检查而不发送
另外,也可以检查元件的数目在一个信道排队通过使用len(ch)
,如在Go specifications说明。 这与cap
结合使我们能够检查一个通道是否已满而不发送任何数据。
if len(ch) == cap(ch) {
// Channel was full, but might not be by now
} else {
// Channel wasn't full, but might be by now
}
注意,比较的结果可以通过时间是无效的,你进入if
块
,而不是我选择丢弃发送到缓冲通道的项目。
这就是所谓的 “爆棚通道”,你会发现蚤的答案eapache/channels/overflowing_channel.go
实施:
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)
但该项目eapache/channels实现其他策略,以及:
OverflowingChannel
实现Channel
界面的方式永远不会阻止作者。
具体来说,如果一个值在其缓冲区已满时写入OverflowingChannel
(或者在未缓冲的情况下,当收件人未准备好时),那么该值将被简单地丢弃。
对于相反的行为(丢弃最旧的元件,而不是最新)看到
RingChannel
。
一个很好的答案。丢失最旧或最新项目的溢出通道有时可能是您工具箱中的重要工具。考虑一个goroutines环:通常,任何循环(a.k.a * cycle *)都存在死锁的风险。将任何一个频道更改为溢出频道都可以解决此问题。失去一些事件并不重要,如果他们是可以变得陈旧的种类可以很容易地被取代。当然有其他方法可以解决相同的死锁问题。 – 2014-09-04 21:39:09
我偶然发现的另一个有用的例子是this nifty implementation的Ring Buffer。
从源引证:
的想法是简单的:通过一个 够程从输入信道到 输出信道将消息转发连接两台缓冲通道。无论何时在 传出通道上不能放置新消息,从传出通道中取出一条消息(即 是缓冲区中最旧的消息),放下它,并将新消息放入新释放的传出消息中渠道。
退房this C version以及...
使用len(channel)
检查有多少元素在渠道目前和比较,为cap(channel)
,其容量:
func TestChannelFull(t *testing.T) {
chansize := 100
ch := make(chan bool, chansize)
t.Log(cap(ch))
t.Log(len(ch))
for len(ch) < cap(ch) {
ch <- true
}
t.Log(len(ch))
t.Log("quit because channel is full")
}
init_test.go:25: 100
init_test.go:26: 0
init_test.go:30: 100
init_test.go:31: quit because channel is full
PASS
- 1. 等待一个缓冲通道充满
- 2. 通道缓冲区如何工作?
- 3. 在golang中创建缓冲通道片段
- 4. Golang - 什么是通道缓冲区大小?
- 5. 何时使用缓冲通道?
- 6. 怎么知道当前缓冲区已经设置标志
- 7. 关闭golang通道
- 8. 我如何知道我的记忆是否已满?
- 9. 如何知道我的WebRequest是否已满?
- 10. 如何知道textFields是全满的
- 11. 需要帮助了解缓冲通道
- 12. 如何确保所有管道缓冲区已被读取?
- 13. 试图填充缓冲区,同时缓冲区写入通道
- 14. 如何知道缓冲区在n音讯
- 15. 如何知道HTML5音频缓冲数据的进度?
- 16. 如何知道缓冲区位置对应的行号?
- 17. 如何知道TCP缓冲区的大小动态
- 18. bash中的缓冲管道
- 19. 我如何知道所显示的图像已被缓存?
- 20. 如何等待缓冲通道(信号量)为空?
- 21. 我将如何在Java中实现Go的无缓冲通道?
- 22. 冲洗管道的缓冲区
- 23. postgresql通知通道
- 24. 如何知道活动已完成?
- 25. 我如何知道视图已移动?
- 26. 我如何知道分栏已完成?
- 27. 我如何知道reloadData已经完成
- 28. 如何知道MediaScanner是否已启用?
- 29. 如何知道MKMapview setRegion:animated:已完成?
- 30. 我如何知道ILMerge已被使用
问题的前提是你想避免频道变满。但是,渠道*可以同步并因此阻止任何一方的事实是CSP思想的重要组成部分。不要过于努力,以防止缓冲区填满,直到您更全面地理解同步。作为练习,请尝试仅使用* unbuffered *通道解决几个问题。然后,您可以看到如何在现有的系统上添加缓冲功能可以提高性能。 (偶尔有太多缓冲可能会降低性能的情况。) – 2014-09-04 21:43:55