【问题标题】:Concurrent write to std::vector to different indices causes crash? [closed]并发写入 std::vector 到不同索引会导致崩溃? [关闭]
【发布时间】:2018-01-19 17:48:23
【问题描述】:

我有一个大向量,我想更新该向量中的一些数据(不插入/删除,而是用指定索引上的另一个元素替换一个元素)。

我认为在 2 个或更多不同的线程上执行工作非常聪明,因此可以提高速度。而且由于在这种情况下实际上不需要同步,因此由于索引不同,这应该非常快。

不幸的是,我的代码崩溃了,要么声明:EXC_BAD_ACCESS,要么“未分配被释放的指针”。

伪代码:

// I have an entries_ vector with data of type DataT

std::vector<std::thread> workers(NUMBER_OF_PARALLEL_CHUNKS);

unsigned long tuplesPerChunk = entries_.size() / NUMBER_OF_PARALLEL_CHUNKS;

for (int j = 0; j < NUMBER_OF_PARALLEL_CHUNKS; ++j) {
    unsigned long offset = tuplesPerChunk * j;

    workers.emplace_back(std::thread([&offset, &tuplesPerChunk, this](){
        for (int i = 0; i < tuplesPerChunk; ++i) {
            unsigned long offsetIndex = offset + i;
            entries_[offsetIndex] = createNewDataForSomeParticularReason();

        }
    }));
}

for (auto &worker : workers) {
    if (worker.joinable()) worker.join();
}

【问题讨论】:

  • 没有更多信息很难回答这个问题。错误发生在代码的什么地方?你试图找出它发生的原因是什么?只有一个线程会发生这种情况吗?只有一个条目的数组?等等。你能让代码更简单,但仍然显示同样的问题吗? (这样做,您可能会弄清楚出了什么问题。)

标签: c++ vector concurrency mutex


【解决方案1】:

按值捕获offset,否则会有悬空指针。

您的线程从循环内部一直存在,直到加入。

offset 只存在于一个循环迭代中。

【讨论】:

  • 这行得通,但你能详细说明一下吗?
  • 准确地说offset 存在于一个循环迭代中。每次迭代都有自己的offset,一旦迭代结束就会消失。
  • @RustyX 不错的收获!尽管从技术上讲这是未定义的行为,但实际上offset 的存储可能会被重用,这意味着过去迭代的线程将在循环运行时读取offset 的当前值,从而引入竞争条件。
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 2015-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
相关资源
最近更新 更多