从 std::scoped_lock 抛出的异常
Posted
技术标签:
【中文标题】从 std::scoped_lock 抛出的异常【英文标题】:exception thrown from std::scoped_lock 【发布时间】:2019-05-14 10:37:15 【问题描述】:我正在尝试从另一个线程锁定互斥体,以清除向量,使用 scoped_lock,期望代码将等到另一个线程释放它。
但是发生的情况是,试图获取锁的函数抛出异常,说明资源正忙。
//Called from thread 1
Foo::DoStuff()
std::scoped_lock<std::mutex>(m_lock);
for (auto thing: stuff) //should be non trivial in size
thing->bar();
//called from thread 0
Foo::ClearStuff()
try
std::scoped_lock<std::mutex>(m_lock); //throws
stuff.clear();
catch (const std::exception& e)
std::cout << e.what() << std::endl;
// device or resource busy: device or resource busy
我的线程知识基于 SDL2 线程库,所以我不确定自己做错了什么。我使用了错误的线程构造吗?如果是这样,我应该使用什么来确保调用等到互斥锁被释放?
【问题讨论】:
std::scoped_lock<std::mutex>(m_lock);
这会创建临时锁 - 未命名的实例,该实例在行尾被销毁。您的代码中没有同步。 bar
和 clear
可能同时发生,导致 UB。
你需要通过给你的作用域锁一个名字来创建一个变量。否则它的作用域只持续到分号。
【参考方案1】:
您需要存储作用域锁。实际上,锁被获取到一个临时变量中,该变量立即被销毁,释放锁。
std::scoped_lock<std::mutex> lock(m_lock);
旁注:我会称它为m_stuff_mtx
而不是m_lock
,因为它控制对stuff
的访问,是一个互斥体,还有其他东西在起作用,称为锁。
【讨论】:
以上是关于从 std::scoped_lock 抛出的异常的主要内容,如果未能解决你的问题,请参考以下文章