TGViewer
BASCODE BASCODE @bascodech · 140 subscribers
Post #120 145
select не опрашивает каналы по кругу.

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

Первое. Когда готовы сразу несколько каналов, select берет не первый по порядку. Он строит pollorder, случайную перестановку кейсов select.go:191, и идет уже по ней. Три всегда готовых канала, 300 тысяч итераций:

case 1 (в исходнике 1-й): 100216  33.4%
case 2 (в исходнике 2-й): 99812 33.3%
case 3 (в исходнике 3-й): 99972 33.3%


Ровно по трети. Без перестановки первый case побеждал бы всегда, а остальные голодали.

Рядом живет второй порядок обхода, совсем про другое: lockorder select.go:206 сортирует каналы по адресу hchan. Это защита от дедлока, когда два select работают на одном наборе каналов. Классическое "бери локи в одном порядке", только внутри рантайма.

Второе. sync.Mutex умеет голодать. Если горутина прождала замок дольше миллисекунды (starvationThresholdNs = 1e6, internal/sync/mutex.go:55, мьютекс переходит в режим голодания и дальше вручает замок первому в очереди напрямую, без розыгрыша.

Восемь горутин дерутся за один замок, критическая секция 30 мкс, я меряю собственное ожидание:

среднее ожидание:   125.855µs
максимум ожидания: 1.076358ms
макс. обгонов: 34


Максимум в двух прогонах подряд встал на 1.076 и 1.079 мс. Это не случайность, это тот самый порог: как только ожидание переваливает за миллисекунду, обгонять больше не дают.

Код обоих замеров лежит в репозитории, каталоги select_fair и mutex_starve.

Деталь, которая удивила меня сильнее всего. Очередь ждущих живет не в мьютексе. В нем 8 байт, очередь туда не влезет физически. Все ждущие лежат в глобальной таблице семафоров рантайма: 251 корзина, в каждой сбалансированное дерево sema.go:49. То есть твой мьютекс не хранит своих ждущих, он хранит только число, а очередь ему подбирают по хешу адреса...
  • 🔥 1
  • 🤯 1
More from @bascodech
  1. Sep 18, 2026Мысли про дебаггинг и IDE в 2026 Вот интересная история... Расс Кокс выложил пять сессий,…
  2. Sep 14, 2026Кодить без AI сейчас как заниматься айкидо. Красиво и глубоко и десять лет до черного пояс…
  3. Sep 7, 2026Выложил свой statusline для claude code в публичный репозиторий. Лимитов у подписки три: п…
  4. Sep 5, 2026Рубрика "лысая мудрость" Как я больше года храбро готовился, но так ничего и не сделал. Вт…
  5. Sep 2, 2026Распаковал 30 релизов Go подряд, 2.9 ГБ исходников. Ради одного вопроса. Вопрос такой: поч…
  6. Aug 29, 2026Сегодня у кого-то будет распаковка :-)
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →