有没有办法知道通道缓冲区中有多少条消息?

huangapple go评论92阅读模式
英文:

Is there a way to tell how many messages are in channel buffer?

问题

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

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

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

英文:

I have identified a bottleneck in my program, it is a buffered channel. I would like to give client an indication of system load, which should be indicated by number of messages buffered in the channel.

Is there a way in Go to tell how many buffered messages there are in a channel?

If you also have a Java background, I am looking for an equivelent of this: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html#size()

答案1

得分: 18

lencap是内置函数,它们接受不同类型的参数,并返回int类型的结果。实现保证结果始终适合int类型。

len(s)函数用于通道,返回通道缓冲区中排队的元素数量。

cap(s)函数用于通道,返回通道缓冲区的容量。

通道的len函数返回通道缓冲区中排队的元素数量。例如,

package main

import "fmt"

func main() {
    ch := make(chan int, 8)
    ch <- 42
    ch <- 7
    <-ch
    ch <- 64
    // 排队的元素数量 = 1 + 1 - 1 + 1 = 2
    fmt.Println(len(ch), cap(ch))
}

输出:

2 8
英文:

> Length and capacity
>
> The built-in functions len and cap take arguments of various types
> and return a result of type int. The implementation guarantees that
> the result always fits into an int.
>
> Call Argument type Result
>
> len(s) chan T number of elements queued in channel buffer
>
> cap(s) chan T channel buffer capacity

The len function for a channel gives the number of elements queued in the channel buffer. For example,

package main

import &quot;fmt&quot;

func main() {
	ch := make(chan int, 8)
	ch &lt;- 42
	ch &lt;- 7
	&lt;-ch
	ch &lt;- 64
	// number of queued elements = 1 + 1 - 1 + 1 = 2
	fmt.Println(len(ch), cap(ch))
}

Output:

2 8

答案2

得分: -2

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

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

func queue(in <-chan string, out chan<- string, query <-chan chan int) {
    buffer := []string{}
    var s string
    var reply chan int
    for {
        // Go的选择语句不支持布尔条件,所以我们需要在选择语句外使用“if”语句
        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)
            }
        }
    }
}
英文:

There is an alternative solution to this using a "queue" process that handles the queueing of messages and also is able to report on its size. For this you will need an input channel and an output channel, plus a query channel through which the size is obtained. Because there will be two input channels, you will need a select (a CSP 'choice') between them.

Here's a little demo of this in operation. The queue consists of a slice as a buffer and an input channel.

func queue(in &lt;-chan string, out chan&lt;- string, query &lt;-chan chan int) {
    buffer := []string{}
    var s string
    var reply chan int
    for {
        // Go select doesn&#39;t support boolean guards so we need the &#39;if&#39; outside the select instead
        if len(buffer) &gt; 0 {
            select {
            case reply = &lt;-query:
                reply &lt;- len(buffer)
            case s = &lt;-in:
                buffer = append(buffer, s)
            case out &lt;- buffer[0]:
                buffer = buffer[1:]
            }
        } else {
            select {
            case reply = &lt;-query:
                reply &lt;- len(buffer)
            case s = &lt;-in:
                buffer = append(buffer, s)
            }
        }
    }
}

huangapple
  • 本文由 发表于 2013年6月10日 11:36:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/17016572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定