【问题标题】:Is there a standard STL or Qt way to yield a mutex if someone else is waiting, otherwise keep it?如果其他人在等待,是否有标准的 STL 或 Qt 方法来产生互斥锁,否则保留它?
【发布时间】:2023-12-19 11:03:02
【问题描述】:

在我的工作线程中,最方便的外循环逻辑是

lock (mutex_foo);

while (not done)
{
    do_some_work ();

    if (someone_is_waiting_for (mutex_foo))
    {
        unlock (mutex_foo);

        wait_until_someone_else_locks (mutex_foo);

        // expect this lock to already be taken,
        // this thread will now wait its turn
        lock (mutex_foo);
    }
}

unlock (mutex_foo);

主线程

while (not_done)
{
    do_stuff ();

    lock (mutex_foo); // this will interrupt the worker thread's main loop

    use_shared_resource ();

    unlock (mutex_foo);
}

我使用 C++11 和 Qt 5。我应该如何实现?

【问题讨论】:

  • 您可以将std::atomic<int> 与互斥锁一起存储,在尝试锁定互斥锁之前增加它,在解锁时减少它。然后您可以检查该值是否为> 1 并且您知道其他人在等待。

标签: c++ multithreading c++11 stl mutex


【解决方案1】:

super 关于使用 std::atomic_int 的建议可能会奏效,但我认为您可能在这里想多了——对于您的工作线程来说,一种更简单、更容易验证的方法是:

while(not done)
{
   lock_mutex();
   do_some_work();
   unlock_mutex();
}

这将允许其他线程在当前对 do_some_work() 的调用返回后立即获得互斥锁的所有权。

如果您担心这会引入额外的互斥锁锁定和解锁,请不要担心 - 互斥锁如今已经得到了很好的优化,它们的 lock_mutex() 和 unlock_mutex() 操作不太可能再出现了比您的 check_if_someone_is_waiting() 功能昂贵。

【讨论】:

  • 你说得对。这比我想象的要简单,我对谁拥有共享数据的模型不好。