有条件地获得 std::mutex

Conditionally acquire an std::mutex

我有一个使用 GPU 的多线程应用程序,它本质上是单线程的,而我使用的实际 API cv::gpu::FAST_GPU 在我尝试多线程使用它们时确实崩溃了,所以基本上我有:

static std::mutex s_FAST_GPU_mutex;

{
    std::lock_guard<std::mutex> guard(s_FAST_GPU_mutex);
    cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
}

现在,对代码进行基准测试显示 FAST_GPU() 在孤立状态下比 CPU FAST() 更快,但在实际应用程序中,我的其他线程花费大量时间等待锁,所以整体吞吐量更差。

查看文档,at this answer 看来这可能是可行的:

static std::mutex s_FAST_GPU_mutex;
static std::unique_lock<std::mutex> s_FAST_GPU_lock(s_FAST_GPU_mutex, std::defer_lock);

{
    // Create an unlocked guard
    std::lock_guard<decltype(s_FAST_GPU_lock)> guard(s_FAST_GPU_lock, std::defer_lock);
    if (s_FAST_GPU_lock.try_lock())
    {
        cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
    }
    else
    {
        cv::FAST(/*parameters*/);
    }
}

但是,这不会编译,因为 std::lock_guard 只接受 std::adopt_lock。我该如何正确实施?

同时从多个线程访问 unique_lock 实际上是不安全的。我不熟悉你问题的 opencv 部分,所以这个答案主要集中在 mutex/lock 用法上。

static std::mutex s_FAST_GPU_mutex;
{
   // Create a unique lock, attempting to acquire
   std::unique_lock<std::mutex> guard(s_FAST_GPU_mutex, std::try_to_lock);
   if (guard.owns_lock())
   {
       cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
       guard.unlock(); // Or just let it go out of scope later
   }
   else
   {
       cv::FAST(/*parameters*/);
   }
}  

这里尝试获取锁,如果成功,使用FAST_GPU,然后释放锁。如果已经获得了锁,则进入第二个分支,调用 FAST

你可以使用std::lock_guard,如果你采用锁定状态的互斥体,像这样:

{
    if (s_FAST_GPU_mutex.try_lock())
    {
        std::lock_guard<decltype(s_FAST_GPU_lock)> guard(s_FAST_GPU_mutex, std::adopt_lock);
        cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
    }
    else
    {
        cv::FAST(/*parameters*/);
    }
}