TGViewer
Библиотека Go (Golang) разработчика Библиотека Go (Golang) разработчика @golang_lib · 2.7K subscribers
Post #700 609
🥊 Каналы vs Мьютексы: Главная ловушка философии Go

Все знают самую знаменитую пословицу Роба Пайка: "Не общайтесь, разделяя память; разделяйте память, общаясь".

Джун читает это и делает вывод: «Мьютексы - это устаревшее зло из C++, каналы - это тру-Go-вей!». И после этого пишет 50 строк кода с горутиной-координатором, select и каналами просто для того, чтобы безопасно инкрементировать счетчик просмотров или обновить мапу.

Сеньор смотрит на это и грустит, потому что знает секрет: под капотом любого канала (в структуре hchan) лежит... обычный мьютекс. Использовать канал просто для защиты переменной - это как купить таксопарк, чтобы один раз съездить за хлебом.

Давайте раз и навсегда проведем границу.

🛡 Когда берем Мьютексы (Состояние)

Если ваша задача - защитить кусок данных (структуру, map, срез) от одновременного изменения, берите sync.Mutex или sync.RWMutex.

- Это быстро: Взять свободный мьютекс - это дешевая атомарная операция (~15-20 наносекунд). Операции с каналами тяжелее, так как требуют работы с внутренними очередями и планировщиком.
- Это просто: mu.Lock() и defer mu.Unlock(). Никаких рисков забыть закрыть канал и получить утечку горутины (Goroutine Leak).
- Идеальный юзкейс: In-memory кэши, хранение сессий, счетчики внутри структур.

🚦 Когда берем Каналы (Оркестрация и Владение)

Каналы нужны не для защиты данных, а для передачи владения (ownership) и управления потоком выполнения.

- Передача эстафеты: Одна горутина скачала кусок данных, отдала его в канал и "забыла" про него. Вторая горутина забрала и начала парсить.
- Оркестрация: Worker Pools, пайплайны (Fan-Out/Fan-In), о которых мы говорили раньше.
- Таймауты и отмены: Вы не можете прервать ожидание mu.Lock() по таймауту. А вот конструкцию select { case <-ch: ... case <-time.After(1*time.Second): ... } - легко.

❌ Классический Антипаттерн:
Создавать отдельную "горутину-хранитель", которая владеет мапой и слушает каналы chanGet и chanSet, чтобы отдавать и записывать значения. Это ад в отладке, работает медленнее мьютекса и требует написания кучи бойлерплейта.

✅ Золотое правило (одобрено разработчиками Go):

- Используйте каналы для маршрутизации данных и контроля за горутинами.
- Используйте мьютексы для защиты внутреннего состояния (state) ваших объектов.

🔥 Senior Tip: Атомики
Если вам нужно защитить не сложную структуру, а просто инкрементировать счетчик или переключить флаг (число или bool), не берите ни мьютексы, ни каналы. Ваш выбор - пакет sync/atomic.
Операция atomic.AddInt64 выполняется на уровне аппаратных инструкций процессора (CAS) и работает так быстро, что вы даже не увидите её в профайлере.

#golang #concurrency #architecture #bestpractices #cleancode

📲 Мы в MAX

👉 @golang_lib
  • 🔥 5
  • 👍 3
  • ❤ 1
More from @golang_lib
  1. Sep 22, 2026🔴AI кодинг интервью с разработчиком из международного FinTech в четверг в 19:00 ДА! Вайбк…
  2. Sep 21, 2026📢 sync.Cond: Как разбудить 10 000 горутин одним вызовом (и не сломать планировщик) Предст…
  3. Sep 17, 2026🔎 pprof: Как найти функцию, которая жрет 80% CPU Сервис на проде внезапно упирается в пол…
  4. Sep 7, 2026🗺️ sync.Map: Почему эта «серебряная пуля» иногда пробивает дно производительности Как тол…
  5. Sep 2, 2026☢️ Пакет unsafe: Взламываем систему типов Go Пакет unsafe - это легальный способ сказать к…
  6. Sep 1, 2026🔴 Тестовое собеседование с Go Senior с опытом работы в Яндексе, EPAM и Uzum в этот четвер…
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 →