Go за Прикладом: Не Блокуючі Операції на Каналах

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

Базові надсилання та отримання на каналах є блокуючими операціями. Однак, ми можемо використовувати select з умовою default для реалізації не блокуючих відправлень, і навіть для не-блокуючих різнонаправлених selectів.

package main
import "fmt"
func main() {
    messages := make(chan string)
    signals := make(chan bool)

Ось не болкуюче приймання. Якщо значення доступне в каналі messages тоді select підбере умову <-messages case з цим значенням. Ні? негайно буде обрана стандартна умова default.

    select {
    case msg := <-messages:
        fmt.Println("отримане повідомлення", msg)
    default:
        fmt.Println("жодних повідомлень не отримано")
    }

Не блокуючі надсилання працюють схожим чином, тут msg не може бути надіслано до каналу messages, тому що цей канал не є буферезованим і тому що немає отримувача. Тому відбудеться стандартна умова default.

    msg := "привіт"
    select {
    case messages <- msg:
        fmt.Println("надіслано повідомлення", msg)
    default:
        fmt.Println("жодних повідомлень не надіслано")
    }

Над стандартною умовою default дозволяється мати більше однієї умови, для імплементації різнонаправлених selectів, умови яких будуть чекати отримання як messages, так і signals.

    select {
    case msg := <-messages:
        fmt.Println("отримано повідомлення", msg)
    case sig := <-signals:
        fmt.Println("отриманий сигнал", sig)
    default:
        fmt.Println("жодної активності")
    }
}
$ go run non-blocking-channel-operations.go
жодних повідомлень не отримано
жодних повідомлень не надіслано
жодної активності

Наступний приклад: Закриття каналів.