Все вопросы

32 Конкурентность

Как устроен канал?

Канал передаёт значения между горутинами. Небуферизованный make(chan int) отдаёт значение только когда на другом конце его уже ждут: отправка и приём встречаются. Буферизованный make(chan int, n) принимает до n значений без встречного приёма.

Закрывает канал отправитель, когда значений больше не будет. Приём из закрытого канала возвращает нулевое значение и ok == false. Цикл for v := range ch сам останавливается на закрытии. Отправка в закрытый канал и закрытие nil-канала паникуют. Чтение и запись в nil-канал блокируются навсегда — это иногда используют в select, чтобы ветка перестала быть готовой.

Пример

Go

отправитель закрывает канал, range его читает

package main

import "fmt"

func main() {
    jobs := make(chan int)
    go func() {
        defer close(jobs)
        for i := 1; i <= 3; i++ {
            jobs <- i
        }
    }()
    for n := range jobs {
        fmt.Println(n)
    }
}