Как реализованы каналы Go?

После (кратко) обзора спецификации языка Go, эффективной версии Go и модели памяти Go, я все еще немного не понимаю, как работают каналы Go под капотом.

Какая у них структура? Они действуют как поточно-безопасная очередь/массив.

Зависит ли их реализация от архитектуры?

Ответ 1

Исходный файл для каналов (из корня исходного кода go) находится в /src/pkg/runtime/chan.go.

hchan - это центральная структура данных для канала, со списками отправки и получения (с указателем на их goroutine и данными элемент) и флаг closed. Там встроенная структура Lock, которая определена в runtime2.go и которая служит в качестве мьютекса (futex) или семафора в зависимости от ОС. Реализация блокировки выполняется в lock_futex.go(Linux/Dragonfly/Some BSD) или lock_sema.go(Windows/OSX/Plan9/Some BSD) на основе тегов сборки.

В этом файле chan.go реализованы все операции с каналом, поэтому вы можете видеть операции makechan, send and receive, а также команды select, close, len и cap.

Для подробного объяснения внутренней работы каналов вы должны прочитать "Переключить каналы на стероиды" самим Дмитрием Вьюковым (Go core dev, goroutines, планировщик и каналы между прочим).

Ответ 3

Вот хороший доклад, который примерно описывает, как реализованы каналы:
https://youtu.be/KBZlN0izeiY

Описание разговора:

GopherCon 2017: Кавья Джоши - Понимание каналов

Каналы обеспечивают простой механизм взаимодействия между программами и мощную конструкцию для создания сложных шаблонов параллелизма. Мы углубимся во внутреннюю работу каналов и операций с каналами, включая то, как они поддерживаются планировщиком времени выполнения и системами управления памятью.