如果互斥锁被锁定,安全地跳过任务
Posted
技术标签:
【中文标题】如果互斥锁被锁定,安全地跳过任务【英文标题】:Safely skip an task if mutex is locked 【发布时间】:2020-05-17 19:07:50 【问题描述】:我正在努力解决互斥锁/锁的问题。 情况:
任务 A 需要相对较长的时间。它在一个线程中不规则地执行(但一次只执行一次)。 有一个任务 B,它很快,并且经常从另一个线程调用。 两个任务都在同一个内存上工作,因此不应同时执行。 任务 B 不等待任务 A 至关重要,因为上下文是在渲染后与 GPU 通信(纹理传输),这会导致帧延迟,因为任务 A 可能需要几个帧。 如果任务 A 当前正在运行,则应该跳过任务 B。 但决不能跳过任务 A到目前为止我所拥有的: 任务 A 的线程(不定期调用):
std::unique_lock<std::mutex> mlock(the_mutex);
TaskA();
还有任务B(挂在渲染线程中)
if mutex.try_lock()
TaskB();
the_mutex.unlock();
The_mutex 是对象的通用 std::mutex。
这一次真的那么容易,还是我错过了什么?在过去烦人的多线程错误之后,我对这个话题变得不安全。 非常感谢。
【问题讨论】:
抽象不是很好吗? :) 【参考方案1】:您的代码是正确的,但为了异常安全和防止资源泄漏,您最好在任务 B 中使用 RAII。一般规则是“使用 RAII 锁守卫(lock_guard、unique_lock、shared_lock),永远不要调用 mutex.lock 和mutex.unlock 直接 (RAII)"。
std::unique_lock<std::mutex> mlock(the_mutex, std::defer_lock);
if (mlock.try_lock())
TaskB();
或
std::unique_lock<std::mutex> mlock(the_mutex, std::try_to_lock);
if (mlock)
TaskB();
【讨论】:
也可以使用std::try_lock
代替std::defer_lock
然后只使用if (mlock)
@AlanBirtles std::try_lock
没有使用RAII,需要mutex::unlock
,所以不如直接使用mutex::lock
。
不知道为什么你认为std::try_lock
与std::defer_lock
有任何不同,如果en.cppreference.com/w/cpp/thread/unique_lock/unique_lock 有区别,那std::unique_lock
就毫无意义了
@AlanBirtles 查看en.cppreference.com/w/cpp/thread/try_lock 上的示例代码,在std::try_lock
之后需要mutex::unlock
。 unique_lock
不是这种情况,您不需要 unlock
,因为析构函数会为您执行此操作。
对不起,我的意思是try_to_lock
以上是关于如果互斥锁被锁定,安全地跳过任务的主要内容,如果未能解决你的问题,请参考以下文章