有没有办法告诉通道缓冲区中有多少消息?

时间:2013-06-10 03:36:55

标签: go

我发现我的程序存在瓶颈,它是一个缓冲通道。我想给客户一个系统负载的指示,这应该通过信道中缓冲的消息数来表示。

Go中是否有一种方法可以告知通道中有多少缓冲消息?

如果你也有Java背景,我正在寻找一个平等的:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html#size()

2 个答案:

答案 0 :(得分:13)

  

Length and capacity

     

内置函数lencap接受各种类型的参数   并返回类型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)
            }
        }
    }
}