В
Владимир Балун
@vladimir_balun_programming7.2K подп.
5.2Kпросмотров
72.5%от подписчиков
12 марта 2026 г.
Score: 5.7K
🧩 А давайте сравним мьютексы в C++ и Go Кажется, что там вообще сравнивать - мьютекс и мьютекс: lock, unlock, критическая секция. Но если посмотреть внутрь, разница довольно интересная и отражает философию самих языков. В C++ стандартный std::mutex - это по сути тонкая обертка над примитивами операционной системы. На Linux это обычно pthread_mutex, который в свою очередь опирается на механизм futex. Как правило, внутри используется такой алгоритм: сначала поток пытается захватить мьютекс через атомарную операцию (fast path). Если мьютекс свободен - все проходит без системного вызова. Если нет - поток переходит в slow path и ядро паркует его до момента, когда мьютекс освободится. Ключевая идея - максимально быстро пройти fast path и не трогать ядро. Но если поток блокируется, он действительно засыпает на уровне операционной системы. Поэтому в C++ мьютексы тесно связаны именно с потоками ОС. В Go ситуация другая, потому что у языка есть собственный рантайм, поэтому мьютекс реализован полностью в рантайме языка. Захват тоже начинается с атомарной операции - если мьютекс свободен, горутина проходит fast path и продолжает выполнение. Но если мьютекс занят, дальше происходит интересное: рантайм может припарковать горутины, а не поток ОС. Это важная разница. В Go блокируется не поток операционной системы, а горутина. Планировщик может тут же запустить другую горутину на том же потоке. Благодаря этому можно иметь десятки тысяч конкурентных задач без огромного количества системных потоков. Еще один интересный момент - режимы работы мьютекса. В Go есть так называемый starvation mode. Если горутина слишком долго ждет мьютекс, рантайм переключается в режим, где владение передается напрямую следующему ожидающему. Это уменьшает вероятность голодания и делает задержки более предсказуемыми. 📌 Снаружи API почти одинаковый: lock и unlock. А внутри - две совершенно разные модели конкурентности. Еще в C++ мьютекс - это не один тип. В стандартной библиотеке есть целое семейство примитивов синхронизации: - std::mutex - обычный мьютекс - std::recursive_mutex - позволяет одному потоку захватывать мьютекс несколько раз - std::timed_mutex - можно ждать мьютекс с таймаутом - std::recursive_timed_mutex - комбинация рекурсивности и таймаута - std::shared_mutex - reader-writer lock (несколько читателей или один писатель) - std::shared_timed_mutex - версия reader-writer lock с таймаутами Плюс есть различные обертки для безопасной работы с ними - например std::lock_guard, std::unique_lock или std::scoped_lock, которые реализуют RAII и автоматически освобождают мьютекс при выходе из области видимости. Теперь посмотрим на Go. В Go все намного проще. Основной мьютекс один - sync.Mutex. Есть еще sync.RWMutex - это reader-writer lock. То есть в Go фактически два базовых примитива блокировок. Идея языка - минимальный набор инструментов. Разработчик не должен выбирать из десятков типов синхронизации. И здесь хорошо видно различие философий C++ и Go. C++ дает много разных примитивов и больше контроля над поведением синхронизации. Go намеренно оставляет всего несколько простых инструментов. То есть C++ - про гибкость и контроль, а Go - про простоту и скорость разработки. Кто я | Навигация | Спасибо
5.2K
просмотров
3225
символов
Да
эмодзи
Нет
медиа

Другие посты @vladimir_balun_programming

Все посты канала →
🧩 А давайте сравним мьютексы в C++ и Go Кажется, что там во — @vladimir_balun_programming | PostSniper