如果互斥锁被锁定,安全地跳过任务

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_lockstd::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::unlockunique_lock 不是这种情况,您不需要 unlock,因为析构函数会为您执行此操作。 对不起,我的意思是try_to_lock

以上是关于如果互斥锁被锁定,安全地跳过任务的主要内容,如果未能解决你的问题,请参考以下文章

互斥量示例/教程? [关闭]

LiteOS 互斥锁机制

TencentOS tiny深度源码分析—— 互斥锁

linux互斥锁简介(内核态)

在互斥锁解锁时取消阻止定时接收

互斥锁