Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QThread - quit()
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Общие вопросы
AD
Проблема следующая. Есть модальное диалоговое окошко, в котором рисуется какой-то график. При открытии окошка запускается параллельный поток, который заполняет необходимый вектор координат графика и постепенно отрисовывается. В функции run() вызывается функция в которой имеется цикл заполнения вектора. Если человек вдруг надоело ждать или он передумал смотреть этот график или ошибся (короче, по любой какой-то причине решил прервать отрисовку) и закрывается окно. При закрытии я вызываю функцию quit()! НО: после выполнения quit() в отладчике вижу, что мы снова попадаем в функцию c циклом. Что необходимо сделать, чтобы этот цикл сразу завершался? Если я после quit() пытаюсь вызвать wait(), то программа конкретно зависает.
SABROG
Цитата(AD @ 23.10.2009, 17:22) *
В функции run() вызывается функция в которой имеется цикл заполнения вектора.


Если ты не вызываешь exec() в run(), чтобы запустить цикл событий и используешь нечто вроде forever() или for(;;), то выхода не будет.
AD
Цитата(SABROG @ 23.10.2009, 17:57) *
Цитата(AD @ 23.10.2009, 17:22) *
В функции run() вызывается функция в которой имеется цикл заполнения вектора.


Если ты не вызываешь exec() в run(), чтобы запустить цикл событий и используешь нечто вроде forever() или for(;;), то выхода не будет.

Цикл, конечно же конечный, но хотелось бы, чтобы он прекращался, как только окно закрывали....
BRE
Цитата(AD @ 23.10.2009, 23:54) *
Цикл, конечно же конечный, но хотелось бы, чтобы он прекращался, как только окно закрывали....

Так введи в цикл еще одно условие для преждевременного выхода.
SABROG
Как я понял за всё время существования потоков ничего кроме жестокого убийства потока и if (terminatedFlag) ничего не придумали?
AD
Цитата(SABROG)
Как я понял за всё время существования потоков ничего кроме жестокого убийства потока и if (terminatedFlag) ничего не придумали?

Да, блин! :(
Цитата
Так введи в цикл еще одно условие для преждевременного выхода.

До этого додумался, но такое решение не нравится. :(
Жаль, что в Qt это не введено еще.
BRE
Цитата(AD @ 24.10.2009, 13:43) *
Жаль, что в Qt это не введено еще.

А что можно ввести? ;)
QEventLoop::exit (quit) и соответственно QThread::quit используют такой же подход со специальной переменной, при изменении которой цикл заканчивается.
В своих циклах нужно использовать свои переменные.

А почему это решение не нравиться?
Cergey
Всегда, если подумать, можно установить условие для выхода!!!

Создавал потоки и так и не понял зачем нужен exec() ( причем тут for ) и что такое event loop!!!
Объяесните кто может??? ;)
AD
Цитата(BRE @ 24.10.2009, 16:50) *
А что можно ввести? ;)
QEventLoop::exit (quit) и соответственно QThread::quit используют такой же подход со специальной переменной, при изменении которой цикл заканчивается.
В своих циклах нужно использовать свои переменные.

А почему это решение не нравиться?

Стоп.... Не пойму о каком еще цикле, который заканчивается, идет речь? Если нет своего цикла, то вообще в функцию run() задет раз и выйдет, все... О каком цикле идет речь, который заканчивается с помощью quit()? Да кстати, exec() никакие циклы не запускает - проверял!

Цитата(BRE @ 24.10.2009, 16:50) *
А почему это решение не нравиться?

Да почему, нормальное решение. Но уж очень какое-то искусственное!
BRE
Цитата(AD @ 24.10.2009, 18:09) *
Да кстати, exec() никакие циклы не запускает - проверял!

Ты ошибаешься.
rnd
AD, приведите минимальный пример
Cergey
Цитата(BRE @ 24.10.2009, 18:17) *
Цитата(AD @ 24.10.2009, 18:09) *
Да кстати, exec() никакие циклы не запускает - проверял!

Ты ошибаешься.

Кто прав???
Litkevich Yuriy
Цитата(Cergey @ 25.10.2009, 15:25) *
Кто прав???
Документация, exec() - запускает цикл обработки событий (тык)
rnd
Кстати, зачем спорить, на то чтобы понять запускает или нет - необходимо 10 сек:
qthread.cpp
int QThread::exec()
{
    Q_D(QThread);
    d->mutex.lock();
    d->data->quitNow = false;
    QEventLoop eventLoop;
    d->mutex.unlock();
    int returnCode = eventLoop.exec();
    return returnCode;
}
BRE
Для удобства можно инкапсулировать все в одном классе:
class ExitFlag
{
public:
    ExitFlag() : m_exit( false ) {}

    void    doExit()
    {
        QMutexLocker lock( m_mutex );
        m_exit = true;
    }
    
    bool isExit() const
    {
        QMutexLocker lock( m_mutex );
        return m_exit;
    }

    operator bool() const
    {
        return isExit();
    }

private:
    mutable QMutex    m_mutex;
    bool            m_exit;
};


использовать этот класс можно примерно так:
class Thread : public QThread
{

public slots:
    void    stop()
    {
        m_exitFlag.doExit();
    }

protected:
    virtual void run()
    {
        while( !m_exitFlag )
        {
            // Долгие вычисления
            if( m_exitFlag.isExit() )
                break;
            // Долгие вычисления
        }
    }

private:
    ExitFlag    m_exitFlag;
};


P.S. Набирал прямо здесь, могут быть опечатки. :)
niXman
Цитата(SABROG @ 23.10.2009, 23:00) *
Как я понял за всё время существования потоков ничего кроме жестокого убийства потока и if (terminatedFlag) ничего не придумали?

Жесткое убийство потоков, это не правильное решение. Не данный момент, самое правильное решение, это if (terminatedFlag)
SABROG
Цитата(niXman @ 26.10.2009, 12:32) *
Жесткое убийство потоков, это не правильное решение.


Правильное/неправильное, а некоторые вещи могут подвесить поток навечно и до проверки флага дело никогда не дойдет.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.