gre*_*ell 2 c++ containers exception std
像std :: vector && friends(我实际上是在使用QList)这样的容器会抛出一个可捕获的异常,或者如果一个线程在另一个线程正在读取它时尝试写入容器,那么它是否是未定义的行为:
std::vector<std::string> stuff;
Run Code Online (Sandbox Code Playgroud)
另一个线程中的非关键任务(例如拼写检查):
try {
for (std::string& s : stuff) {
//do stuff with s
}
} catch (...) { // Handle all exceptions
//bail out of task
}
Run Code Online (Sandbox Code Playgroud)
主线程:
stuff.erase(std::remove(someIterator), stuff.end());
Run Code Online (Sandbox Code Playgroud)
所以你可以看到这里会有一个场景,它可能会有一个无效的迭代器,并且会在读取线程中抛出异常 - 这将被捕获并且只是从任务中解脱出来.
但这只是一种情况 - 我可以依赖从这些容器中抛出可捕获的异常,这样我就不需要使用互斥锁保护向量或字符串了吗?或者是否会有一些情况可以解除引用nullptr(或其他东西)并导致SEH异常 - 即我无法捕获并继续的东西.我认为答案是它可能依赖于实现,并且最有可能导致未定义的行为,但我想我会问这个问题.
一般来说,你不能指望访问一个无效的迭代器抛出任何类型的异常.结果是未定义的行为:调用可能会抛出,它可能会崩溃,它可能会工作多年然后再咬你,它可能会打破程序中其他地方无关的东西.
标准禁止在标准库的对象和功能上进行此类操作:
17.6.4.10/1:
如果从不同线程调用标准库函数可能引入数据争用,则程序的行为是不确定的.可能发生这种情况的条件在17.6.5.9中规定.
17.6.5.9/6:
通过调用标准库容器或字符串成员函数获得的迭代器操作可以访问底层容器,但不得修改它.[ 注意:特别是,使迭代器无效的容器操作与与该容器关联的迭代器上的操作冲突.- 结束说明 ]
大多数Qt函数同样不是线程安全的.
如果您需要在线程之间共享数据,请保护自己免受数据争用.除非文档说明,否则不要依靠库来为您完成.
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |