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

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

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

package main
import "fmt"

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

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) з Каналами.