Каким образом std::mutex функционирует?

  • 30 августа 2023 г. 16:17
Ответы на вопрос 2
std::mutex является типом данных в стандартной библиотеке C++, предназначенным для реализации механизма блокировки и синхронизации доступа к общим данным из разных потоков. 

std::mutex обеспечивает две основные операции: lock() и unlock(). Когда поток пытается заблокировать мьютекс с помощью операции lock(), если мьютекс свободен, то поток блокирует его и продолжает выполнение. Если же мьютекс уже заблокирован другим потоком, то текущий поток приостанавливается до тех пор, пока мьютекс не будет разблокирован. Когда поток закончил работу с общими данными, он должен разблокировать мьютекс с помощью операции unlock(), чтобы дать возможность другим потокам получить доступ к данным.

Правильное использование мьютексов в данном случае включает следующие шаги:
1. Определите std::mutex в вашем классе в качестве члена данных для контроля доступа к общим данным.
2. Перед тем, как поток будет изменять или читать общие данные, он должен заблокировать мьютекс с помощью операции lock(). Если мьютекс уже заблокирован другим потоком, текущий поток ожидает его разблокировки.
3. После завершения операций с общими данными, поток должен разблокировать мьютекс с помощью операции unlock(), чтобы дать возможность другим потокам получить доступ к данным.

Важно помнить, что при использовании мьютексов необходимо обеспечить согласованность использования общих данных и избегать ситуаций взаимной блокировки (deadlock) или гонок данных (data race). Следует также учитывать производительность программы при использовании мьютексов, так как блокировка и разблокировка мьютекса может быть дорогой операцией.

Рекомендуется ознакомиться с документацией по std::mutex и другим средствам синхронизации в C++ для более глубокого понимания и эффективного использования мьютексов в ваших программных проектах.
Энтони Уильямс: C++. Практика многопоточного программирования.

Вы не блокируете поток, вы блокируете мьютекс. Если мьютекс уже заблокирован другим потоком, то второй поток будет ожидать освобождения мьютекса, а затем заблокирует его. Ожидание происходит в методе lock мьютекса. Есть также метод try_lock, который не ожидает, но если мьютекс уже захвачен другим потоком, то возвращается ошибка.

В общем случае использование мьютекса выглядит так:
m.lock()
<небезопасная операция>
m.unlock()

Конструкторы можно не удалять, просто в них нужно заблокировать мьютекс источника объекта. Мьютекс назначения блокировать не нужно, так как это конструктор, и класс только создается, никто им еще не владеет, поэтому доступ к его членам будет монопольным. Однако в этих конструкторах нужно создать новые мьютексы для объекта назначения.

Кстати, можете ли вы создать мьютекс таким образом?
std::shared_ptr m = std::make_shared( );
Похожие вопросы