我正在考虑使用以下代码:
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();
}
但是,从文档中我不清楚如果将try_lock_until()
实现为忙等待,或者线程将在尝试之间产生/睡眠(这是我想要的行为)。这是在最小化线程资源使用的同时查询锁的最佳方法吗?
答案 0 :(得分:2)
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).