Número de elementos en un canal

86

Usando un canal con búfer, ¿cómo se miden cuántos elementos hay en el canal? Por ejemplo, estoy creando y enviando un canal como este:

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

Quiero medir cuántos mensajes hay en el canal send_ch .

Soy consciente de que, debido a la simultaneidad, la medición no será exacta, ya que podría producirse un adelanto entre la medición y la acción (por ejemplo, lo que se analiza en este video Google I / O 2012 - Go Concurrency Patterns ). Usaré esto para el control de flujo entre productores y consumidores, es decir, una vez que haya pasado por una marca de agua alta, cambiaré algo de comportamiento hasta que vuelva a pasar por una marca de agua baja.

Sonia Hamilton
fuente

Respuestas:

150

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

func len (v Type) int
La función incorporada len devuelve la longitud de v, según su tipo:

  • Array: el número de elementos en v.
  • Puntero a matriz: el número de elementos en * v (incluso si v es nulo).
  • Slice o map: el número de elementos en v; si v es nulo, len (v) es cero.
  • Cadena: el número de bytes en v.
  • Canal: el número de elementos en cola (no leídos) en el búfer del canal; si v es nulo, len (v) es cero.
package main

import "fmt"

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

dará salida:

34
Artem Shitov
fuente
4
Gracias Artem. Ese es un uso inesperado de len: ¡hubiera esperado que devolviera la capacidad de un canal, no la cantidad de elementos que contiene! Es bueno saberlo, gracias de nuevo.
Sonia Hamilton
39
Si hubiera querido la capacidad, entonces la función incorporada caplo haría.
ANisus
6
Lo que me parece interesante aquí es que si el canal se hace sin capacidad ( c := make(chan int)) no se puede obtener su longitud. No he encontrado una razón para esto. Sí, su capacidad también regresa a 0
Brettski
Me parece extraño que cuando no está almacenado en búfer, no pueda obtener su longitud. Y cuando se usan goroutines, se estropea un poco.
Berkant Ipek
6
@Brettski y Berkant, si el canal no tiene búfer (capacidad = 0), la longitud siempre será cero. El remitente bloquea hasta que el receptor recibe el valor. golang.org/doc/effective_go.html#channels
Farshid T