6

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

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

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

4

2 回答 2

17

长度和容量

内置函数lencap接受各种类型的参数并返回 type 的结果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
于 2013-06-10T04:05:42.630 回答
-1

有一个替代解决方案使用“队列”进程来处理消息的排队,并且还能够报告其大小。为此,您将需要一个输入通道和一个输出通道,以及一个用于获取大小的查询通道。因为会有两个输入通道,所以您需要在它们之间进行选择(CSP“选择”)。

这是一个运行中的小演示。队列由一个作为缓冲区的切片和一个输入通道组成。

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)
            }
        }
    }
}
于 2013-06-11T09:15:05.167 回答