Как часто mutex::lock() проверяет наличие разблокированного состояния, если оно уже заблокировано другим потоком?
Согласно cppreference, построение std::lock_guard
с std::mutex
параметр вызывает lock()
метод этого mutex
,
Согласно cplusplus, относительно mutex
"s lock()
метод:
Если мьютекс заблокирован другим потоком, выполнение вызывающего потока блокируется, пока другой поток не будет разблокирован...
Я не уверен, правильно ли сформулирован титульный вопрос, поэтому я поставил его в контексте приведенного ниже кода.
Я хотел проверить это и посмотреть, действительно ли вызывающий поток ожидает разблокировки вместо того, чтобы прекратить выполнение его вызываемого (например, функции, функтора, лямбды) и / или выдать исключение. Следующий код имеет два потока t1
а также t2
каждая построена с указателем на одну и ту же функцию foo
, Каждый звонок foo
будут sleep_for
определенное количество времени, определяемое foo
"s unsigned
параметр num
перед выполнением кода, защищенного блокировкой. Сам код, защищенный замком, содержит другой sleep_for
период, чтобы сделать любой заблокированный период выполнения более очевидным:
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
std::mutex m;
void foo(unsigned num) {
std::this_thread::sleep_for(std::chrono::milliseconds(num * 10));
std::lock_guard<std::mutex> guard(m);
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
std::cout << num << std::endl;
}
int main() {
std::thread t1(foo, 10);
std::thread t2(foo, 5);
t1.join();
t2.join();
}
Консольный вывод:
5
10
Это займет около / не менее 3,05 секунд для 5
выводить. Это займет около / по крайней мере дополнительные 3 секунды для 10
выводить. Это означает t2
сначала выполняет защищенный код, так как он имеет меньшее время ожидания перед блокировкой mutex
,
Я предполагаю, что однажды звонок foo
из потока t1
добирается до lock_guard
линия и находит mutex
был уже заблокирован t2
, t1
не прекращает выполнение или выбрасывает исключение. t1
просто ждет его разблокировки.
Как часто std::mutex::lock()
или же std::lock_guard
сделать эту проверку для разблокировки? Насколько дорогой чек? Проверка осуществляется следующим образом?
while (some_mutex.try_lock() == false) {
std::this_thread::sleep_for(std::chrono::milliseconds(1))
}
// execute lock-protected code
2 ответа
Как часто std::mutex::lock() или std::lock_guard делают эту проверку для разблокировки?
Это не так. Он блокируется внутри операционной системы, пока ресурс не будет освобожден. Любая операционная система, которая реализовала это путем вращения, будет причиной для жалоб.
Мьютексы обычно предоставляются ОС, то есть за все это отвечает модель потоков вашей ОС. Эти детали не указаны или даже не реализованы в C++.
Таким образом, в некоторой степени это будет зависеть от ряда факторов, таких как загрузка процессора всеми процессами, относительный приоритет процесса, относительный приоритет потока...
Просто слишком много, чтобы дать четкий ответ для вас, даже если такая вещь будет полезна.