Liczba elementów w kanale

86

Jak mierzyć liczbę elementów w kanale za pomocą kanału buforowanego? Na przykład tworzę i wysyłam na takim kanale:

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

Chcę zmierzyć ile wiad są w kanale send_ch .

Zdaję sobie sprawę, że ze względu na współbieżność pomiar nie będzie dokładny, ponieważ między pomiarem a działaniem może wystąpić wywłaszczanie (np. Omówione w tym filmie Google I / O 2012 - Go Concurrency Patterns ). Użyję tego do kontroli przepływu między producentami a konsumentami, tj. Gdy przejdę przez wysoki znak wodny, zmieniając pewne zachowanie, aż przejdę z powrotem przez niski znak wodny.

Sonia Hamilton
źródło

Odpowiedzi:

150

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

func len (v Type) int
Funkcja wbudowana len zwraca długość v, zgodnie z jej typem:

  • Tablica: liczba elementów w v.
  • Wskaźnik do tablicy: liczba elementów w * v (nawet jeśli v jest zerowe).
  • Slice lub map: liczba elementów w v; jeśli v jest zerowe, len (v) jest równe zero.
  • Ciąg: liczba bajtów w v.
  • Kanał: liczba elementów w kolejce (nieprzeczytanych) w buforze kanału; jeśli v jest zerowe, len (v) jest równe zero.
package main

import "fmt"

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

wyświetli:

34
Artem Shitov
źródło
4
Dzięki Artem. To nieoczekiwane użycie len - spodziewałem się, że zwróci pojemność kanału, a nie liczbę jego elementów! Dobrze wiedzieć, jeszcze raz dziękuję.
Sonia Hamilton,
39
Gdybyś chciał mieć taką pojemność, capzrobiłaby to wbudowana funkcja .
ANisus
6
To, co uważam za interesujące, to fakt, że jeśli kanał jest wykonany bez pojemności ( c := make(chan int)), nie można uzyskać jego długości. Nie znalazłem powodu. Tak, jego pojemność również wraca jako 0
Brettski
Dziwnie się czuję, że kiedy jest niebuforowany, nie mogę uzyskać jego długości. A kiedy używasz goroutines, to trochę psuje.
Berkant Ipek
6
@Brettski i Berkant, Jeśli kanał jest niebuforowany (pojemność = 0), długość zawsze będzie wynosić zero. Nadawca blokuje się, dopóki odbiorca nie otrzyma wartości. golang.org/doc/effective_go.html#channels
Farshid T