c++ 锁定通过螺纹保持太长时间

qmelpv7a  于 2023-01-06  发布在  其他
关注(0)|答案(3)|浏览(112)

我有一个应用程序,其中多个线程共享一个互斥锁。

std::lock_guard< std::recursive_mutex > lock(globalMutex_);

一个集中(T1),另一个集中(T2,T3..)。我有一个例子,在成功获取锁之前,不太需要锁的线程被阻塞了100秒。
获得锁定的胎面(T1so)通常以如下方式进行:

void func()
{
  std::lock_guard< std::recursive_mutex > lock(globalMutex_);
  processing();
}

globalMutex_然后被周期性地很好地释放。

奇怪的行为:
T1在总共100秒的时间段内系统地获取锁,而另一个线程根本不获取锁

(In其他线程我有相同的模式,但其他函数调用较少)

**问题:**这是什么原因?这是正常行为吗?

  • 环境:* 我使用的是Windows 10 /最新版本的Visual Studio / 64位/ GUI应用程序
  • 注意:* 即使我将T2置于高优先级,情况也是一样的。
46scxncf

46scxncf1#

std::mutex不保证互斥锁按照线程调用lock()的顺序锁定。当线程释放锁时,如果该线程快速重新锁定该锁,则除非另一个线程已经在等待该锁并且正在同时执行,否则第一个线程很可能成功地重新获得该锁。
最简单的解决方案是将锁保持尽可能短的时间,并尝试确保每个线程至少有一段时间不锁定互斥锁。
更复杂的解决方案是创建你自己的互斥锁类,它确实提供了一些关于锁定/解锁顺序的保证,你可以用std::mutexstd::condition_variable的组合来实现它。

qlckcl4x

qlckcl4x2#

这看起来像一个错误:

{
  std::lock_guard< std::recursive_mutex > lock(globalMutex_);
  processing();
}

processing()是做什么的?如果它花费的时间超过几微秒,那么可能有一个更有效的方法来解决你的问题。有时它看起来像这样:

bool success=false;
while (! success) {
    auto result = speculative_processing();
    {
        std::lock_guard< std::recursive_mutex > lock(globalMutex_);
        success = attempt_to_publish(result);
    }
}

多线程程序中的单个线程经常需要做额外的工作来避开彼此的干扰,但通过避开彼此的干扰,它们能够更好地利用多个处理器,更快地完成整个工作。

nafvub8i

nafvub8i3#

您将使用condition_variable实现您的目标。

std::condition_variable cv;
bool busy = false;
void func()
{
  {
    std::unique_lock<std::mutex> lk(globalMutex_);
    cv.wait(lk, []{return !busy;});
    busy = true;
  }
  processing();
  busy = false;
  cv.notify_one();
}

相关问题