<mutex> 和 <condition_variable>的异常处理
Exception handling for <mutex> and <condition_variable>
假设
- 没有未定义的行为发生
- 不会发生死锁
- 互斥被正确的线程以正确的顺序锁定和解锁正确的次数
- 非递归互斥不是多次锁定的
- 锁定递归互斥不超过所有权的最大级别
- 没有传递给条件变量throw的谓词,并且
- 只有标准库提供的时钟、时间点和持续时间才能与
std::
互斥对象和条件变量一起使用
是否保证对不同类型的std::
互斥和条件变量进行操作(而不是构造它们)不会引发任何异常(尤其是std::system_error
类型的异常)?
例如,在使用以下方法的情况下:
void MyClass::setVariable() {
std::lock_guard<std::mutex> const guard(m_mutex);
m_var = 42; // m_var is of type int
m_conditionVariable.notify_all();
}
void MyClass::waitVariable() {
std::unique_lock<std::mutex> lock(m_mutex);
m_conditionVariable.wait(lock, [this]() noexcept { return m_var == 42; });
}
假设noexcept
安全吗?还是应该在调用站点周围写一些try-catch块?或者有什么需要注意的地方吗?
请考虑C++11、C++14及更高版本中所有类型的互斥和条件变量。
简短回答:没有(对不起)
如果底层同步对象无法执行其操作,则这些操作中的任何一个都将抛出std::system_error
。
这是因为同步原语的正确操作取决于:
-
可用的系统资源。
-
程序的某些其他部分不会使原始无效
尽管公平地说,如果(1)正在发生,那么可能是时候重新设计应用程序或在负载较低的机器上运行它了。
如果(2)正在发生,则程序在逻辑上不一致。
话虽如此,
还是应该在调用点周围写一些try-catch块?
也没有
您应该在以下条件下编写try/catch块:
-
当程序能够对错误情况做一些有用的事情时(例如修复它或询问用户是否想再试一次)
-
您想向错误添加一些信息并重新抛出它,以便提供诊断面包屑跟踪(例如嵌套异常)
-
您希望记录故障并继续。
否则,c++异常处理的全部意义在于,允许RAII处理资源重新获取,并允许异常在调用堆栈中向上流动,直到它找到一个想要处理它的处理程序
创建面包屑轨迹的示例:
void wait_for_object()
try
{
_x.wait(); // let's say it throws a system_error on a loaded system
}
catch(...)
{
std::throw_with_nested(std::runtime_error(__func__));
}
感谢T.C.现在提供的链接,我同意——您的代码应该是安全的。由于未来标准device_or_resource_busy
将被删除,并且正如该问题的作者所说,这种情况不可能以任何合理的方式发生,因此lock
只有两种可能性:
(13.1)--operation_not_permitted--如果线程没有执行操作的权限。
(13.2)--resource_deadlock_would_ecurse--如果实现检测到会出现死锁。
这两种情况都被你的先决条件排除在外。因此,您的代码应该可以安全地使用noexcept。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中