Количество элементов в канале

86

Как измерить количество элементов в канале, используя буферизованный канал? Например, я создаю и отправляю такой канал:

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

Я хочу измерить, сколько сообщений находится в канале send_ch .

Я знаю, что из-за параллелизма измерение не будет точным, поскольку между измерением и действием может произойти упреждение (например, обсуждается в этом видео Google I / O 2012 - Go Concurrency Patterns ). Я буду использовать это для управления потоком между производителями и потребителями, то есть после того, как я прошел через высокий водяной знак, изменяя некоторое поведение, пока я не прохожу обратно через низкий водяной знак.

Соня Гамильтон
источник

Ответы:

150

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

func len (v Type) int
Встроенная функция len возвращает длину v в соответствии с его типом:

  • Массив: количество элементов в v.
  • Указатель на массив: количество элементов в * v (даже если v равно нулю).
  • Срез или карта: количество элементов в v; если v равно нулю, len (v) равно нулю.
  • Строка: количество байтов в v.
  • Канал: количество элементов в очереди (непрочитанных) в буфере канала; если v равно нулю, len (v) равно нулю.
package main

import "fmt"

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

выведет:

34
Артем Шитов
источник
4
Спасибо, Артем. Это неожиданное использование len - я ожидал, что он вернет емкость канала, а не количество элементов в нем! Полезно знать, еще раз спасибо.
Соня Гамильтон,
39
Если вам нужна емкость, встроенная функция capсделает это.
ANisus
6
Что меня интересует, так это то, что если канал сделан без емкости ( c := make(chan int)), вы не можете получить его длину. Я не нашел для этого причины. Да, его емкость также возвращается как 0
Бреттски
Мне странно, что когда он небуферизован, я не могу понять его длину. А при использовании горутин это вроде как портится.
Беркант Ипек
6
@Brettski and Berkant, если канал не буферизован (емкость = 0), длина всегда будет равна нулю. Отправитель блокируется до тех пор, пока получатель не получит значение. golang.org/doc/effective_go.html#channels
Фаршид Т.