【发布时间】:2010-12-10 14:57:50
【问题描述】:
在我的代码中使用已检查的 STL 实现时出现意外断言失败。
经过一番研究,我将问题缩小到一个向量中的 push_back,该向量是从与创建向量的线程不同的线程调用的。
重现此问题的最简单代码是:
class SomeClass
{
private:
std::vector<int> theVector;
public:
SomeClass ()
{
theVector.push_back(1); // Ok
}
void add()
{
theVector.push_back(1); // Crash
}
};
唯一的区别是 SomeClass 是从我的主线程实例化的,而 add 是从另一个线程调用的。但是,不存在并发问题:在我用于故障排除的最简单形式的代码中,除了我上面提到的情况之外,没有人从这个向量中读取或写入。
跟踪 push_back 代码,我注意到 std::vector 中的某些方法(如 count() 或 size())在从另一个线程(方法“add”)调用时返回垃圾,并在从创建线程(例如在构造函数中)
我是否应该断定 std::vector 在多线程环境中不可用?或者有没有解决这个问题的方法?
编辑:删除易失性
编辑 2:您认为问题可能不在于多线程吗?在我的测试运行中, add 仅被调用一次(使用断点验证)。如果我从构造函数中删除 push_back,我仍然会崩溃。所以最后,即使只调用一次向量的方法,在调用一次的函数中也会使断言失败。因此不能有并发,或者......?
【问题讨论】:
-
如果确实没有并发向量应该工作。如果有 2 个或更多线程并行使用向量,这将不起作用。
-
您是否处于每个线程都有自己的堆的环境中?
-
-1:您的代码甚至无法编译,因为
push_back()未声明为“易失性”。能否提供更详细的代码/说明? -
“我应该断定 std::vector 在多线程环境中不可用吗?” -- 一点也不,vector 在多线程应用程序中的作用与在单线程应用程序中的作用不一样。事实上,如果你比较 C++0x(它是线程感知的)向量与 C++97(它不是线程感知的)没有任何不同。在必要时提供序列化是应用程序而不是向量的责任。在您的情况下,我认为您关于多线程在可观察行为中没有作用的断言可能是错误的,请进行适当的锁定而不是推测。
-
@JimR - 那会是什么?线程始终共享同一个免费存储,这是线程安全的,这是标准要求。
标签: c++ multithreading stl vector thread-safety