Número de elementos em um canal

86

Usando um canal com buffer, como medir quantos elementos existem no canal? Por exemplo, estou criando e enviando um canal como este:

send_ch := make(chan []byte, 100)
// code
send_ch <- msg

Quero medir quantas msgs estão no canal send_ch .

Estou ciente de que, devido à simultaneidade, a medição não será exata, pois pode ocorrer preempção entre a medição e a ação (por exemplo, discutido neste vídeo Google I / O 2012 - Go Concurrency Patterns ). Usarei isso para controle de fluxo entre produtores e consumidores, ou seja, uma vez que passei por uma marca d'água alta, mudando algum comportamento até passar de volta por uma marca d'água baixa.

Sonia Hamilton
fonte

Respostas:

150

http://golang.org/pkg/builtin/#len

func len (v Type) int
A função interna len retorna o comprimento de v, de acordo com seu tipo:

  • Array: o número de elementos em v.
  • Ponteiro para a matriz: o número de elementos em * v (mesmo se v for nulo).
  • Slice, ou map: o número de elementos em v; se v for nulo, len (v) será zero.
  • String: o número de bytes em v.
  • Canal: o número de elementos enfileirados (não lidos) no buffer do canal; se v for nulo, len (v) será zero.
package main

import "fmt"

func main() {
        c := make(chan int, 100)
        for i := 0; i < 34; i++ {
                c <- 0
        }
        fmt.Println(len(c))
}

irá produzir:

34
Artem Shitov
fonte
4
Obrigado Artem. Esse é um uso inesperado de len - eu esperava que ele retornasse a capacidade de um canal, não o número de elementos nele! É bom saber, obrigado novamente.
Sonia Hamilton,
39
Se você desejasse a capacidade, a função incorporada capfaria isso.
ANisus
6
O que acho interessante aqui é que se o canal for feito sem capacidade ( c := make(chan int)) você não poderá obter seu comprimento. Eu não encontrei um motivo para isso. Sim, a capacidade também retorna como 0
Brettski
Eu me sinto estranho porque, quando está sem buffer, não consigo obter seu comprimento. E ao usar goroutines, meio que bagunça.
Berkant Ipek
6
@Brettski e Berkant, Se o canal não tiver buffer (capacidade = 0), o comprimento será sempre zero. O emissor bloqueia até que o receptor receba o valor. golang.org/doc/effective_go.html#channels
T