Кількість елементів у каналі


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
T,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.