Я хочу запустить несколько парсеров MuparserX одновременно, используя QThreadPool. Вот код:
#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 работают нормально. Есть ли какой-то нюанс компилятора Microsoft, который является причиной этого, или моя программа неверна?
Я нашел обходной путь для этой проблемы, хотя не совсем чистое решение. Ошибка возникает в mup::IToken::~IToken()
когда макрос MUP_LEAKAGE_REPORT
определено. Макрос (автоматически определяемый в сборках отладки) вызывает статический член не поточно-ориентированным способом, что приводит к ошибке итератора. Простое решение — просто закомментировать строку, в которой определен макрос. В моей версии MuparserX он находится в mpDefines.h, строка 100:
#define MUP_LEAKAGE_REPORT
Насколько я могу судить, макрос используется только для отладки MuparserX и не влияет на поведение анализатора.
Других решений пока нет …