Reputation: 8273
I'm thinking of using the following code:
auto now = std::chrono::high_resolution_clock::now();
std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
if(lock.try_lock_until(now + std::chrono::milliseconds(15))
{
// swap some buffer pointers...
lock.unlock();
}
However, it's not clear to me from the documentation if try_lock_until()
is implemented as a busy wait or if the thread will yield/sleep in between tries (which is my desired behavior). Is this the best way to query a lock while minimizing thread resource usage?
Upvotes: 2
Views: 2426
Reputation: 1139
The CppReference page for std::unique_lock::try_lock_until
indeed only states it "Blocks until specified timeout_time
has been reached or the lock is acquired". This is not just a shortcoming of the website though. The standard (I used the November 2014 working draft) carefully steers clear of specifying whether a thread
has to yield
while blocking on any kind of mutex
, talking only about acquiring ownership.
For std::mutex
, for instance, section 30.4.1.2.1 states
If one thread owns a
mutex
object, attempts by another thread to acquire ownership of that object will fail (fortry_lock()
) or block (forlock()
) until the owning thread has released ownership with a call to unlock().
No mention of scheduling or yield
ing is made at all, though.
Furthermore, even if it did mention yield
explicitly, that wouldn't help that much, as this_thread::yield
(section 30.3.2) merely "Offers the implementation the opportunity to reschedule".
CppReference makes this more concrete, stating
The exact behavior of this function depends on the implementation, in particular on the mechanics of the OS scheduler in use and the state of the system. For example, a first-in-first-out realtime scheduler (SCHED_FIFO in Linux) would suspend the current thread and put it on the back of the queue of the same-priority threads that are ready to run (and if there are no other threads at the same priority, yield has no effect).
So I'm afraid the question of how try_lock_until
is implemented in C++ cannot be answered. Perhaps you can ask a new question targeting a specific platform. For your second question ("Is this the best way to query a lock while minimizing thread resource usage?") the answer is yes, the best option your platform offers should be invoked using this API (though, as T.C. commented, try_lock_for
seems like a better fit).
Upvotes: 3