我发现我的程序存在瓶颈,它是一个缓冲通道。我想给客户一个系统负载的指示,这应该通过信道中缓冲的消息数来表示。
Go中是否有一种方法可以告知通道中有多少缓冲消息?
如果你也有Java背景,我正在寻找一个平等的:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html#size()
答案 0 :(得分:13)
内置函数
len
和cap
接受各种类型的参数 并返回类型int
的结果。实施保证了这一点 结果总是适合int
。Call Argument type Result len(s) chan T number of elements queued in channel buffer cap(s) chan T channel buffer capacity
通道的len
函数给出了通道缓冲区中排队的元素数。例如,
package main
import "fmt"
func main() {
ch := make(chan int, 8)
ch <- 42
ch <- 7
<-ch
ch <- 64
// number of queued elements = 1 + 1 - 1 + 1 = 2
fmt.Println(len(ch), cap(ch))
}
输出:
2 8
答案 1 :(得分:-1)
使用“队列”进程可以替代解决方案,该进程处理消息的排队并且还能够报告其大小。为此,您需要一个输入通道和一个输出通道,以及一个通过其获取大小的查询通道。因为将有两个输入通道,所以它们之间需要选择(CSP'选择')。
这是运作中的little demo。队列由作为缓冲区的切片和输入通道组成。
func queue(in <-chan string, out chan<- string, query <-chan chan int) {
buffer := []string{}
var s string
var reply chan int
for {
// Go select doesn't support boolean guards so we need the 'if' outside the select instead
if len(buffer) > 0 {
select {
case reply = <-query:
reply <- len(buffer)
case s = <-in:
buffer = append(buffer, s)
case out <- buffer[0]:
buffer = buffer[1:]
}
} else {
select {
case reply = <-query:
reply <- len(buffer)
case s = <-in:
buffer = append(buffer, s)
}
}
}
}