有条件地获得 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*/);
}
}
我有一个使用 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*/);
}
}