QThreadPool pure virtual method called

126
28 ноября 2019, 12:40

В конструкторе окна создаю объект Runnable:

testTask = new TestTask();
testTask->setAutoDelete(true);
connect(testTask, &TestTask::endTest, this, &MainWindow::endTest);

По нажатию кнопки запускаю:

void MainWindow::runTest()
{
    // Если тест не запущен, то запускаем.
    if (!testRunning)
    {
        bool startedTest = QThreadPool::globalInstance()->tryStart(testTask);
        if (!startedTest)
        {
            syslog("Тест не был запущен, нет свободных потоков", E);
        }
        else
        {
            testRunning = true; // помечаем, что тест уже запущен
            syslog("Тест запущен", I);
        }
    }
    else
    {
        syslog("Тест уже выполняется, ожидайте", E);
    }
}

При получении сигнала о завершении теста:

void MainWindow::endTest()
{
    QThreadPool::globalInstance()->waitForDone(); // нужно ли?
    testRunning = false; // помечаем, что тест уже окончен
    syslog("Тест окончен", I);
}

Код таска:

void TestTask::run()
{
    qDebug() << "Hello world from thread" << QThread::currentThread();
    // имитация работы процесса
    QThread::sleep (5);
    emit endTest(); 
}

Результат:

"Тест запущен"
Hello world from thread QThread(0x274c4338, name = "Thread (pooled)")    
"Тест окончен"

После повторного нажатия кнопки, после первого окончания теста, получаю

"Тест запущен" 
pure virtual method called

И программа падает. Если создание объекта Runnable помещаю в слот нажатия кнопки, то все работает хорошо. Т.е. При каждом нажатии кнопки новый объект, и у него запускается run. Но ведь в документации сказано, что tryStart может быть вызвано многократно у того же Runnable.

Answer 1

Вы ж сами указали testTask->setAutoDelete(true); После выполнения таска - QThreadPool его удалил, и при повторной попытке запустить выполнение,

bool startedTest = QThreadPool::globalInstance()->tryStart(testTask);

testTask - уже удален и указывает в мусор.

Выхода два:

  1. testTask->setAutoDelete(false);, но тогда не забыть в деструкторе его удалить самому.

  2. При нажатие кнопки, каждый раз создавать новый TestTask

P.S. в документации не нашел указания на то, что tryStart можно многократно вызывать.

READ ALSO
Как узнать, имеет ли класс определенного родителя?

Как узнать, имеет ли класс определенного родителя?

Как узнать, имеет ли класс определенного родителя?

100
Как запретить пользователю вводить в QLineEdit что-либо кроме URL?

Как запретить пользователю вводить в QLineEdit что-либо кроме URL?

Как запретить пользователю вводить в QLineEdit что-либо кроме URL?

126
Обход сцен графа

Обход сцен графа

Здравствуйте у меня есть SceneGraph состоящий из Node:

112