将 MuparserX 与 QThreadPool 一起使用时程序崩溃

Posted

技术标签:

【中文标题】将 MuparserX 与 QThreadPool 一起使用时程序崩溃【英文标题】:Program crash when using MuparserX with QThreadPool 【发布时间】:2017-09-21 18:59:49 【问题描述】:

我想使用 QThreadPool 同时运行多个 MuparserX 解析器。代码如下:

#include <iostream>
#include <QRunnable>
#include <QThreadPool>
#include "mpParser.h"

struct Task: public QRunnable 
    void run() override 
        //Create a new parser
        mup::ParserX p;
    
;

int main(int argc, char *argv[])

    for (int i = 0; i != 10; ++i)
        QThreadPool::globalInstance()->start(new Task);

    while (QThreadPool::globalInstance()->activeThreadCount() > 0) 

    return 0;

但是,我的程序因析构函数 mup::ParserX::~ParserX() 中的“列表迭代器不兼容”或“列表迭代器不可取消引用”错误而崩溃。这仅在 MSVC13 和 15 中发生,并且仅在调试版本中发生;发布构建运行没有错误并产生预期的输出。 GCC 调试和发布版本都可以正常工作。是微软编译器的一些细微差别导致了这种情况,还是我的程序不正确?

【问题讨论】:

并且仅在调试版本中; -- 该消息仅出现在 Visual C++ 程序的调试版本中,而不是发布版本中。 这只发生在 MSVC13 和 15 上 -- 如果它只发生在单个编译器的一个版本上,你需要担心你的程序有问题,不是编译器。 那么,错误可能也发生在其他版本中,只是不可见? MSVC 在调试模式下进行迭代检查。我不知道其他编译器。在发布模式下,不会检查任何迭代器,因此任何错误都会导致未定义的行为,包括似乎可以正常工作。 @Mike 我在使用QtConcurrent::run 排队并使用QFuture::waitForFinished 等待时遇到同样的崩溃。我认为问题在于 MuparserX 不是线程安全的。 【参考方案1】:

我找到了解决此问题的方法,但并不是真正干净的解决方案。当定义宏 MUP_LEAKAGE_REPORT 时,错误发生在 mup::IToken::~IToken() 中。宏(在调试版本中自动定义)以非线程安全的方式调用静态成员,从而导致迭代器错误。简单的解决方案是只注释掉定义宏的行。在我的 MuparserX 版本中,它位于 mpDefines.h 第 100 行:

  #define MUP_LEAKAGE_REPORT

据我所知,该宏仅用于调试 MuparserX,对解析器的行为没有任何影响。

【讨论】:

以上是关于将 MuparserX 与 QThreadPool 一起使用时程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何覆盖 PyQt5 QThreadPool?

QThreadPool 上的 QSqlDatabase 池

使用 QThreadPool 并行运行单元测试任务

QThreadPool maxThreadCount 在 Application 和 DLL 中不同

在 QThreadPool 中执行槽

QThreadPool 强制停止在 qt cpp