Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: TaIRou от Апрель 19, 2013, 18:40



Название: Переодическая остановка/запуск цикла событий потока
Отправлено: TaIRou от Апрель 19, 2013, 18:40
В классе QThread реализованы две функции необходимые для запуска цикла событий exec() и exit(). Существует ли возможность узнать в каком состоянии находится цикл событий потока (запущен ли он вообще), чтобы затем выполнить exit()? Потоку иногда приходится обрабатывать внутренние задачи, поэтому приходится иногда завершать цикл событий.

Вот реализация exec()
Код:
int QThread::exec()
{
    Q_D(QThread);
    QMutexLocker locker(&d->mutex);
    d->data->quitNow = false;
    if (d->exited) {
        d->exited = false;  // этой строки нет в Qt 4.7
        return d->returnCode;
    }
    locker.unlock();

    QEventLoop eventLoop;
    int returnCode = eventLoop.exec();

    locker.relock();
    d->exited = false;
    d->returnCode = -1;
    return returnCode;
}

Из-за того что строки d->exited = false; нет в младшей версии Qt, которой приходится пользоваться, не представляю, как можно безболезненно вызвать exit() до exec(), потому что иногда такая ситуация возможна. Так как exec() не сбрасывает флаг exited, при следующем вызове exec() функция не пойдет дальше и eventLoop.exec(); выполнен не будет уже никогда.

Рад любой помощи.


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: Bepec от Апрель 19, 2013, 19:42
По-моему у вас что то странное в проекте. Да и в сообщении :D

Сразу завершить поток нельзя. Можно лишь флагами в ключевых местах прерывать обработку.

PS isRunning в качестве "узнавания" состояния не подходит? :)


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: TaIRou от Апрель 19, 2013, 20:01
По-моему у вас что то странное в проекте. Да и в сообщении :D

Сразу завершить поток нельзя. Можно лишь флагами в ключевых местах прерывать обработку.

PS isRunning в качестве "узнавания" состояния не подходит? :)

попробуйте перечитать)
не поток завершить, а выйти из внутренней петли событий, запущенной по exec(), без ущерба для ее повторного запуска.
QThread::isRunning() или QEventLoop::isRunning() имеется в виду? Если первое, то не подходит, если второе, то я разумных способов достучаться до него не вижу.


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: Old от Апрель 19, 2013, 20:03
Я не могу понять, почему не сделать наследника QThread, где и контролировать все что захочется.


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: TaIRou от Апрель 19, 2013, 20:05
Я не могу понять, почему не сделать наследника QThread, где и контролировать все что захочется.


Наследник есть. Только контролировать, что захочется ума не хватает, вот и написал)


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: Bepec от Апрель 19, 2013, 20:09
У вас какое то извращённое решение, чесслово.

Вы пытаетесь создать что-то вроде событийного потока, но что за монстр у вас получится в результате я не могу даже догадываться.

Ну и просто совет - если вам нужны "петли" и прочие непонятные мне термины, то отнаследуйтесь и сделайте событийный поток с флагами. И будет у вас довольно таки сносная система.

PS ещё тут ходит байка, что если написать чего хочется (не алгоритм, не желаемый код, а конечный результат), то могут предложить решение лучше чем то, что видется вам.


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: Old от Апрель 19, 2013, 20:10
Наследник есть. Только контролировать, что захочется ума не хватает, вот и написал)
Сами запускайте очередь, сами останавливайте. Не могу понять в чем проблема, хотя и смысла в этом я тоже не вижу.



Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: TaIRou от Апрель 19, 2013, 20:21
Сами запускайте очередь, сами останавливайте. Не могу понять в чем проблема, хотя и смысла в этом я тоже не вижу.

Я не знаю, как узнать запущена очередь или нет. Метод exec() должен вызываться в run() потока, exit() должен вызываться во внешнем потоке. Таким образом существует вероятность, что я еще не выполнил exec(), а exit() уже сделал. Соответственно exit() выставит внутренний флаг, после чего exec() (в ранних реализациях Qt) никогда не запустит очередь (цикл, петлю, кому как нравится (= ) событий.

ps. Или имеется в виду запустить свою очередь минуя exec()?


Название: Re: Переодическая остановка/запуск цикла событий потока
Отправлено: Old от Апрель 19, 2013, 20:39
ps. Или имеется в виду запустить свою очередь минуя exec()?
Ну тут по другому и не получиться.
Отдельная нить запускается только после вызова start и работает до завершения run.
Т.е. первая остановка этой очереди завершит и поток.
Поэтому, нужно переопределять run, в котором запускать свой цикл, внутри которого запускать свою очередь.

Но, смысла в этом я не вижу. Если вы опишите по подробней что вы хотите сделать, возможно найдутся решения и без подобных заморочек.