Reputation: 1801
According to cppreference, constructing an std::lock_guard
with a std::mutex
parameter calls the lock()
method of that mutex
.
According to cplusplus, regarding mutex
’s lock()
method:
If the mutex is locked by another thread, execution of the calling thread is blocked until unlocked by the other thread...
I'm not sure if the titular question is worded properly, so I put it in the context of the below code.
I wanted to test this and see if a calling thread actually waits for the unlocking instead of terminating execution of its callable (e.g. function, functor, lambda) and/or throwing an exception. The following code has two threads t1
and t2
, each constructed with a pointer to the same function foo
. Each call to foo
will sleep_for
a certain amount of time, determined by foo
's unsigned
parameter num
, before executing the lock-protected code. The lock-protected code itself contains another sleep_for
period, to make any blocked execution period more obvious:
#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();
}
Console Output:
5
10
It takes about/at least 3.05 seconds for the 5
to output. It takes about/at least an additional 3 seconds for the 10
to output. This means t2
gets to execute the protected code first, since it has the lesser wait time prior to the locking of the mutex
.
I’m assuming once the call to foo
from thread t1
gets to the lock_guard
line and finds the mutex
had already been locked by t2
, t1
doesn’t terminate execution or throw an exception. t1
just waits for it to be unlocked.
How frequently does std::mutex::lock()
or std::lock_guard
make this check for the unlocking? How costly is the check? Is the check implemented like the following?
while (some_mutex.try_lock() == false) {
std::this_thread::sleep_for(std::chrono::milliseconds(1))
}
// execute lock-protected code
Upvotes: 0
Views: 686
Reputation: 311048
How frequently does std::mutex::lock() or std::lock_guard make this check for the unlocking?
It doesn't. It blocks inside the operating system until the resource is released. Any operating system that implemented this by spinning would be cause for complaint.
Upvotes: 4
Reputation: 385385
Mutexes are typically provided by the OS, meaning your OS's threading model is responsible for all of this. These details are not specified or even implemented by C++ at all.
As such, to a degree, it will depend on a number of factors such as CPU load across all processes, relative process priority, relative thread priority...
There's just far too much going on to give a clear-cut answer for you, even if such a thing would be useful.
Upvotes: 2