假设
- 没有未定义的行为,
- 没有死锁,
- 通过正确的线程以正确的顺序锁定和解锁互斥锁正确的次数,
- 非递归互斥锁未被多次锁定,
- 锁定递归互斥锁不会超过 最高所有权,
- 没有谓词传递给条件变量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
或者应该在callites周围写一些try-catch块?或者有任何警告吗?
请考虑C ++ 11,C ++ 14及更高版本中所有类型的互斥锁和条件变量。
感谢 链接 T.C。现在提供我会说是 - 您的代码应该是安全的。因为在未来的标准 device_or_resource_busy
将被删除,并且由于该问题的作者说这种情况不能以任何合理的方式发生,那么只有2种可能性 lock
投掷:
(13.1) - operation_not_permitted - 如果线程没有
特权执行操作。
(13.2) - resource_deadlock_would_occur - 如果实现检测到
会发生僵局。
并且这两种情况都被您的前提条件排除在外。所以你的代码应该安全使用noexcept。
简答:不(对不起)
任何这些操作都会抛出 std::system_error
如果基础同步对象无法执行其操作。
这是因为同步原语的正确操作取决于:
可用的系统资源。
程序的其他一些部分不会使原语无效
虽然公平地说,如果(1)正在发生,可能是时候重新设计应用程序或在负载较少的机器上运行它。
如果(2)发生,程序在逻辑上不一致。
话虽如此,
或者应该在callites周围写一些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__));
}