gpt4 book ai didi

c++ - 多个线程在同一个 vector 的不同 vector 上并发添加元素发生错误

转载 作者:行者123 更新时间:2023-12-01 13:34:10 25 4
gpt4 key购买 nike

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>

struct A {
std::vector<int> a;
};

struct B{
std::vector<A> b;
std::mutex mtx;
};

void work(int id, struct B& b) {
std::unique_lock<std::mutex> lck(b.mtx);

b.b.push_back(A());
struct A& a = b.b.back();

lck.unlock();

for(int i = 0; i < 1000; i++) {
std::cout << id << " " << i << std::endl;
a.a.push_back(i);
}
}

int main() {
struct B b;
std::thread t1, t2;

t1 = std::thread([&] {
work(1, b);
});

t2 = std::thread([&] {
work(2, b);
});

t1.join();
t2.join();

return 0;
}

此代码出现一些错误(如段错误)

正如我上面写的, struct B有一个 vector struct Astruct A有一个 vector int .
  • 步骤1)每个线程推新struct A元素与临界区相同的 vector ( b.b )。
  • 步骤 2) 之后,每个线程推送新的 int vector 的元素 astruct A每个创建都没有临界区。

  • 我认为将新元素同时推送到同一个 vector 应该会出现一些问题,但是将新元素同时推送到不同的 vector 不应该发生错误。

    如果我把整个 work函数进入临界区,它不会发生错误。

    所以,我得出结论,将新元素推送到不同的 vector 不会发生错误,但是如果它们在同一个 vector 中,则会发生错误。

    但我无法解释原因。有人请告诉我这件事。 :(

    最佳答案

    当第二个线程将新值推送到 b.b 时这个 vector 可能会被调整大小。如果它被调整大小,所有对它的元素的引用都会失效。所以引用A& a的第一个线程无效。

    你可以

  • 使用 std::list (链表)
  • resize() vector b.b在使用它之前,所以以后不需要调整它的大小(或 reserve() ,在这里没有太大区别)
  • 关于c++ - 多个线程在同一个 vector 的不同 vector 上并发添加元素发生错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60651007/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com