C++ STL 向量的映射/向量和线程安全

发布于 2024-10-12 07:30:58 字数 947 浏览 6 评论 0原文

我想知道以下代码是否被认为是线程安全的。我认为应该是,但我不太熟悉幕后发生的事情。

基本上,我在 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 地图的范围也相同吗?如果没有,请解释一下。干杯!

I was wondering whether following code would be considered thread-safe. I think it should be, but am not too familiar with what goes on under the hood.

Basically, I have this function in class Foo that will be called on the main thread and takes a vector as an anrgument, ie,

void Foo::func( vector<int> v)

In Foo, I also have a private member,

vector< vector<int> > vecOfVec;

Within func, I'll simply push back any new v onto vecOfVec and check for v 's size. If v is smaller than its expected size, I'd like to kick off another thread that fills up v with some known, predetermined values, like so

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 would, as its name suggests simply fill up the vector at 'vecOfVec[index]' with zeros until its size grows to 1000;

Now, I don't see any concurrent read or write operations here on any of the elements of vecOfVec. Obviously, there is a chance of concurrent operations on the entire object, but there will never be concurrencies on a particular element of vecOfVec.

Could someone explain as to whether the above would be considered thread-safe? Would the same extent to STL maps also? If not, please explain. Cheers!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

探春 2024-10-19 07:30:58

我认为,这不是线程安全的。如果一个线程将一个新元素推送到向量上,导致向量的内部内存区域需要增长,会发生什么情况?推送线程可能会将内存交换为更大的缓冲区,这可能会导致与此操作并行读取的线程突然从无效(无效)内存中读取。或者线程在某些槽中看到随机值,只是因为它们同时读取将向量内容从旧内存位置复制到新内存位置的代码。

I think, that this is not thread-safe. What happens, if one thread pushes a new element onto the vector, which causes the vector's internal memory area to need to grow? The pushing thread might exchange the memory for a larger buffer, which can cause threads reading in parallel to this operation to suddenly read from invalid(ated) memory. Or threads seeing random values in certain slots, just because they read concurrently to the code which copies the contents of the vector from the old memory location to the new one.

静赏你的温柔 2024-10-19 07:30:58

如果您的 Foo::PushBackZerosFoo::func( vectorv) 具有相同的签名,那么它将是线程安全的,因为您传递了该函数的数组。所以不会出现并发访问。

If your Foo::PushBackZeros has the same signature as Foo::func( vector<int> v), then it will be thread safe, since you pass a copy of the array to that function. So there will be no concurrent access.

嗼ふ静 2024-10-19 07:30:58

vecOfVec 是按值传递的,因为 boost::bind 要求您在引用参数周围放置 boost::ref 。

所以可能是线程安全的,但没有按照你的想法去做。

我不知道为什么你需要传递该参数,因为它已经在“this”中。

为了回答你想要做什么的最初问题:

  • 如果 vecOfVecs 可以调整大小,那么它的任何成员都可能无效,因此它不是线程安全的。
  • 将成员推入内部向量之一不会使任何其他成员向量无效,因此您可以让不同的线程同时填充不同的向量成员,只要它们都已存在即可。
  • 如果您提前“保留”,那么您可以将更多成员推回到您的向量中,直到达到该容量,并且不会使现有成员无效。

vecOfVec is being passed by value because boost::bind requires you to put a boost::ref around a reference parameter.

So likely thread-safe but not doing what you think it is.

I am not sure why you need to pass that parameter in, as it is already in "this".

To answer the original question though for what you want to do:

  • If vecOfVecs may be resized then any of its members could be invalidated so it would not be thread-safe.
  • Pushing members into one of the inner vectors will not invalidate any other member vectors, so you could have different threads populating different vector members at the same time as long as they are all already there.
  • If you "reserve" ahead then you can push_back more members into your vector until that capacity is reached and it won't invalidate existing members.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文