【发布时间】:2011-01-18 14:42:53
【问题描述】:
我想知道下面的代码是否会被认为是线程安全的。我认为应该是,但对引擎盖下发生的事情不太熟悉。
基本上,我在类 Foo 中有这个函数,它将在主线程上调用,并将向量作为参数,即,
void Foo::func( vector<int> v)
在 Foo 中,我还有一个私人成员,
vector< vector<int> > vecOfVec;
在func 内,我只需将任何新的v 推回vecOfVec 并检查v 的大小。如果v 小于其预期大小,我想启动另一个线程,用一些已知的预定值填充v,就像这样
void Foo::func( vector<int> v)
{
int size = v.size();
int index = vecOfVec.size();
vecOfVec.push_back(v);
if (size < 1000)
{
boost::thread t( boost::bind( &Foo::PushBackZeros, this, vecOfVec, index) );
}
}
Foo::PushBackZeros 顾名思义,只需用零填充 'vecOfVec[index]' 处的向量,直到其大小增长到 1000;
现在,我在vecOfVec 的任何元素上看不到任何并发读取或写入操作。显然,对整个对象有并发操作的机会,但在vecOfVec 的特定元素上永远不会有并发操作。
有人能解释一下上述是否被认为是线程安全的吗? STL映射的范围也相同吗?如果不是,请解释。干杯!
【问题讨论】:
-
产生另一个线程调用 PushBackZeros 的目的是什么?
-
您应该对标准库 (STL) 的线程安全做出的唯一假设是它们不是线程安全的,并且由于该假设而进行防御性编程。跨度>
-
这只是一个理想化的例子。我只是对更一般的情况感兴趣,在这种情况下,您对 STL 容器的元素进行操作,其中元素一旦被推送到主线程上,就不会被主线程访问/读取/写入。
-
多线程是很棘手的,没有锁就需要非常注意所有细节。这意味着您不能相信综合理想化示例的答案将适用于您的特定问题。特别是,不同的容器有不同的实现,对一个元素的操作可能会对其他元素产生影响(删除向量中的第一个元素会通过移动它们来影响所有其他元素,在向量末尾添加一个元素可能会使其增长并影响所有其他人,插入地图可以重新平衡树并影响其他线程中的查找...
标签: c++ boost stl thread-safety containers