Go в примери: Неспъващи действия с канали

Изпращането по канал и получаването по канал по подразбиране спъва (блокира) главната нишка на изпълнението. Въпреки това можем да използваме select с допълнителна клауза – default1, за да осъществим неспъващи изпращания, получавания и дори неспъващи множествени избори2.


  1. default – стойност (в случая – избор) по подразбиране
  2. multi-way select - множествен избор за действие с канал – избор от повече канали, но не задължително с разлчни посоки на действията – получаване и изпращане.
package main
import "fmt"
func main() {
    писма := make(chan string)
    сигнали := make(chan bool)

Ето едно неспъващо получаване. Ако в канала писма вече има стойност, тогава select ще влезе в случая <-писма и ще вземе тази стойност. Иначе ще влезе в подразбирания случай default.

    select {
    case писмо := <-писма:
        fmt.Println("получено писмо:", писмо)
    default:
        fmt.Println("няма нови писма")
    }

Неспъващото изпращане работи по подобен начин. Тук писмо не може да бъде изпратено по канала писма, защото каналът няма зададена вместимост (значи не задържа) и няма получател. Затова бива избран случаят default.

    писмо := "hi"
    select {
    case писма <- писмо:
        fmt.Println("изпратено писмо", писмо)
    default:
        fmt.Println("не е изпратено писмо")
    }

Можем да имаме повече случаи над случая по подразбиране default и така да осъществим множествен неспъващ избор. Тук осъществяваме неспъващ главната нишка избор от каналите писма и сигнали.

    select {
    case писмо := <-писма:
        fmt.Println("получено писмо", писмо)
    case sig := <-сигнали:
        fmt.Println("получен сигнал", sig)
    default:
        fmt.Println("бездействие")
    }
}
$ go run non-blocking-channel-operations.go
няма нови писма
не е изпратено писмо
бездействие

Следващ пример: .