❌

Normal view

Многопоточность в Rust: как Ownership, Send и Sync помогают бороться с гонками данных

В предыдущей статье мы разобрали гонку данных в C++: десять потоков увеличивают общий счётчик, но без синхронизации программа может работать некорректно.

Теперь решим ту же задачу на Rust.

Разберём, как модель владения и система типов помогают предотвращать небезопасный доступ к общим данным, зачем нужны Arc, Mutex и AtomicUsize, а также какую роль играют Send и Sync.

На практических примерах сравним независимые вычисления, совместное изменение состояния и ожидание событий через Condvar.

Отдельно поговорим о том, чего Rust не гарантирует автоматически: логические ошибки, взаимные блокировки и проблемы координации потоков всё ещё требуют внимания разработчика.

Это продолжение серии о системном программировании на C++ и Rust — с кодом, разбором механизмов и практическими выводами.

Читать далее

Один счётчик, десять потоков и неправильный результат: разбираемся в многопоточности C++

Представим простую задачу: десять потоков должны увеличить общий счётчик по миллиону раз. Математика элементарная — в результате ожидаем десять миллионов.

Но программа может вывести совсем другое число. Причём ошибка не обязательно будет повторяться при каждом запуске.

Разберёмся, почему так происходит, как исправить проблему с помощью std::mutex и std::atomic, когда нужны std::condition_variable и std::future, а также чем std::jthread удобнее обычного std::thread.

Все примеры рассчитаны на C++20, если не указано иное.

Читать далее
❌