Go за Прикладом: Закриття каналів

Work in Progress / Сайт в процесі розробки

Закриття каналу вказує на те, що більше жодних значень в нього відправлено не буде. Це стає в нагоді при передачі повідомлення про завершення до отримувачів каналу.

package main
import "fmt"

В цьому прикладі ми скористаємось каналом jobs для комунікації задач між горутиною в main() та робочою горутиною. Коли роботи більше немає - ми закриємо канал jobs за допомогою close.

func main() {
    jobs := make(chan int, 5)
    done := make(chan bool)

Це робоча горутина, вона безперервно отримує з каналу jobs завдання (за допомогою j, more := <-jobs). У цій конструкції якщо more буде false канал jobs закриється і всі значення з нього будуть вийняті. Ми сокритсємось цим для відправки в канал done повідомлення що завдання закінчені і програма може завершити свою роботу.

    go func() {
        for {
            j, more := <-jobs
            if more {
                fmt.Println("отримане завдання", j)
            } else {
                fmt.Println("усі завдання отримані")
                done <- true
                return
            }
        }
    }()

Оце надішле 3 задачі до робочої горутини через канал jobs, після чого закриє його.

    for j := 1; j <= 3; j++ {
        jobs <- j
        fmt.Println("надіслано завдання", j)
    }
    close(jobs)
    fmt.Println("усі завдання надіслані")

Ми чекаємо коли горутина робітник використає синхронізацію що ми бачили раніше.

    <-done
}
$ go run closing-channels.go
надіслано завдання 1
надіслано завдання 2
надіслано завдання 3
усі завдання надіслані
отримане завдання 1
отримане завдання 2
отримане завдання 3
усі завдання отримані

Ідея закритих каналів приводить нас до наступного прикладу: використання range з каналами.

Наступний приклад: Діапазон (Range) з Каналами.