将 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 一起使用时程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章