有条件地获得std :: mutex

Ken*_*Y-N 1 c++ opencv mutex c++11

我有一个使用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*/);
}
Run Code Online (Sandbox Code Playgroud)

现在,对代码进行基准测试显示我FAST_GPU()处于隔离状态比CPU快FAST(),但在实际应用程序中,我的其他线程花费大量时间等待锁定,因此整体吞吐量更差.

仔细阅读文档,在这个答案中,这似乎是可能的:

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*/);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*e S 9

unique_lock从多个线程同时访问实际上是不安全的.我不熟悉你问题的opencv部分,所以这个答案主要关注互斥锁/锁的使用.

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*/);
   }
}  
Run Code Online (Sandbox Code Playgroud)

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

  • 我不能肯定地说,但是分离工作几乎肯定会在CPU接触数据的任何时候迫使GPU上的命令缓冲区停止,因为它必须重新上载该数据才能工作,这个命令缓冲区停止可能导致gpu操作根据实施情况阻止锁内部. (2认同)

Vic*_*nko 5

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*/);
    }
}
Run Code Online (Sandbox Code Playgroud)