【问题标题】:Accessing vector.front() in a thread causes runtime error在线程中访问 vector.front() 会导致运行时错误
【发布时间】:2014-06-09 21:19:48
【问题描述】:

我对向量有一个奇怪的问题,我在主线程中初始化了一个类成员向量,然后调用了一个尝试访问该向量的 front() 的线程。但是访问向量前端会导致运行时错误

这是主线程的代码(dispatchQueueEngine 类的私有类成员)

dispatchQueue.push_back(TempObj);
boost::thread processThread(&Engine::initializeExecutorService, this);
processThread.start_thread();
processThread.join();

而成员函数initializeExecutorService的代码如下(processingQueue为私有类成员)

while (nextIterationAvailable) {
    if (pendingProcess) {

        processingQueue.push_back(dispatchQueue.front());
        dispatchQueue.pop_back();
    }
}

如果我用主线程调用 initializeExecutorService 可以正常工作

更新

调试器报告

收到的信号:SIGSEGV(分段错误)对于程序 postmaster-cpp-ng-obj,pid 13,614 您可以丢弃信号或转发它,您可以继续或暂停该过程

当我尝试使用 Netbeans 运行时,它会报告

运行完成;分段故障;核心转储;

运行 gdb 显示

[启用使用 libthread_db 进行线程调试]
使用主机 libthread_db 库“/lib/x86_64-linux-gnu/libthread_db.so.1”。
[新线程 0x7ffff68e8700 (LWP 13821)]
[新线程 0x7ffff60e7700 (LWP 13822)]
[新线程 0x7ffff58e6700 (LWP 13823)]
程序收到信号 SIGSEGV,分段错误。
[切换到线程 0x7ffff60e7700 (LWP 13822)]
0x00007ffff79cba1b 在?? () 来自 /usr/lib/libboost_thread.so.1.54.0

【问题讨论】:

  • 请编辑您的帖子并添加确切的错误。
  • 可能不相关,但您的代码排在了队列的前面,但弹出了后面?
  • pendingProcess 是如何同步的?
  • 第一个front调用崩溃了吗?或者在崩溃发生之前是否有多次循环迭代?无论如何,它看起来像是一个你应该真正关注的逻辑错误。如果向量有多个条目,那么您可能删除了错误的条目。
  • 如果没有 SSCE,我们可以真正告诉您的是,您可能在某处存在数据竞争(程序单线程运行,多线程崩溃)或您认为 nextIterationAvailable && pendingProcess 暗示的逻辑错误!dispatchQueue.empty().

标签: c++ multithreading vector


【解决方案1】:

当向量为空时,std::vector::front 失败。

这是一个安全的版本:

// lock dispatchQueue
if(!dispatchQueue.empty()) {
    processingQueue.push_back(dispatchQueue.front());
    dispatchQueue.pop_back();
}
// unlock dispatchQueue

另外使用第一个元素并删除最后一个看起来很可疑。

【讨论】:

  • 实际上,在检查 dispatchQueue 是否为空之前不锁定它是不安全的。此外,我知道 dispatchQueue 不为空,并且由于标志 pendingProcess 将永远不会调用此代码
  • 另外使用第一个元素并删除最后一个看起来很可疑。在任何时候向量中只有一个项目,所以第一个和最后一个项目是相同的
  • @Kami: 1) 首先它不是线程安全的。 2)那你为什么需要/使用队列?
  • 1) 我不需要线程安全,因为我不会对 dispatchQueue 进行并发更改 2) 它不是队列,它的向量队列没有 push_back 和 pop_back 函数它们是只需按下并弹出
【解决方案2】:

除了 Danvil 的回应,我想补充一点。可能这会有所帮助,因为一旦我在多线程应用程序中遇到类似问题。

您还应该检查 dispatchQueue 状态是否有效。在我们的应用程序中,另一个线程正在删除向量,它在代码 sn-p 下崩溃。

if(myvector.size)

我们已使用 Windbg 来诊断问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    相关资源
    最近更新 更多