MXStat
MXStat
Введите текст для поиска
Расширенный поиск каналов
  • Вход на сайт
  • Каталог
    Каталог каналов Региональные подборки Поиск каналов
    Добавить канал
  • Рейтинги
    Рейтинг каналов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Max
Библиотека Go (Golang) разработчика

19 Aug, 10:38

Открыть в Max Поделиться

🥊 Каналы 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

👉 @golang_lib

443 6
Каталог
Каталог каналов Подборки каналов Поиск каналов Добавить канал
Рейтинги
Рейтинг каналов Max
Контакты
Написать в Max Написать в Telegram Написать на почту
Всякая всячина
Пользовательское соглашение Политика конфиденциальности
Наши каналы
MXStat в Telegram MXStat в Max
Наши боты
MXAuthBot MXAnalyticsBot
Made by TGStat