Небуферизованный канал

Небуферизованный канал в Go обеспечивает синхронную передачу данных между горутинами. При отправке значения в небуферизованный канал, отправляющая горутина блокируется до тех пор, пока другая горутина не получит это значение. Аналогично, при попытке получить значение из пустого канала, горутина блокируется до появления данных. Первым параметром функция make принимает тип канала, а вторым - емкость, которая для небуферизованного канала равна 0 или опускается.

Синтаксис

goch := make(chan int)

Для отправки данных в канал используется оператор <-, для получения - также <-.

goch <- 42  // отправка
val := <-ch // получение

Пример

Давайте создадим небуферизованный канал и передадим в него значение из одной горутины:

gopackage main

import (
  "fmt"
)

func main() {
  ch := make(chan int)

  go func() {
    ch <- 42
  }()

  res := <-ch
  fmt.Println(res)
}

Результат выполнения кода:

go"42"

Пример

Рассмотрим пример синхронизации двух горутин через небуферизованный канал:

gopackage main

import (
  "fmt"
)

func main() {
  ch := make(chan string)

  go func() {
    ch <- "Hello from goroutine"
  }()

  msg := <-ch
  fmt.Println("Received:", msg)
}

Результат выполнения кода:

go"Received: Hello from goroutine"

Пример

Давайте продемонстрируем блокировку при отправке в небуферизованный канал без получателя:

gopackage main

func main() {
  ch := make(chan int)
  ch <- 42 // deadlock: no receiver
}

Результат выполнения кода:

go"fatal error: all goroutines are asleep - deadlock!"

Смотрите также

  • концепцию каналов,
    которая лежит в основе взаимодействия горутин
  • операцию отправки,
    которая используется для передачи данных в канал
  • операцию получения,
    которая используется для извлечения данных из канала
  • конструкцию select,
    которая позволяет ожидать операции с несколькими каналами