Вопросы о реализации QThread в моем приложении? - PullRequest
2 голосов
/ 16 марта 2012

Как предложено в этом вопросе , я сейчас пытаюсь включить многопоточность.

В соответствии с ссылками, данными karlphillip , я понимаю, что документация по подклассамQThread не должен следовать и использовать moveToThread(), как объяснено.Теперь я вижу, что стандартная реализация QThread run() имеет только exec(), который затем должен быть завершен путем вызова quit(), когда рабочий поток завершил операции.Теперь у меня есть несколько вопросов, чтобы я лучше понимал:

QApplication* ptrApp=new QApplication(argc,argv);
QThread* th=new QThread;
MyClass* obj=new MyClass;
obj->moveToThread(th);
QObject::connect(th,SIGNAL(started()),obj,SLOT(someFunct()));
QObject::connect(obj,SIGNAL(over()),th,SLOT(quit()));
th->start();
//some GUI code in main thread here
return ptrApp->exec();
  1. Что произойдет, если я продолжу использовать someFunct() даже после того, как издаю over() из someFunct()?Это неопределенное поведение или нормальное?

  2. С каким потоком теперь будет связан obj (в то время как остальная часть кода после выдачи over() все еще выполняется в someFunct)?Насколько я понимаю: это не может быть в th, когда у меня quit() этот поток ... quit() будет помещен в очередь, пока exec() в основном потоке не выполнит его, что приведет к exec() в run()из th для выхода (надеюсь, я здесь не ошибаюсь).Я предполагаю, что поток больше не существует.

  3. Как только слот quit() для th выполнен, можно ли предположить, что поток действительно завершился, или я должен продолжить подключение finished() сигнал th в какой-то слот, чтобы быть абсолютно уверенным?

Ответы [ 2 ]

1 голос
/ 16 марта 2012
  1. Неважно, будет ли цикл событий завершен, somefunct() будет продолжать работать до тех пор, пока не вернет управление в ныне исчезнувший цикл.

  2. obj остается связанным с потоком, поэтому, если излучается сигнал, подключенный к одному из его слотов, слот не будет работать, но он будет поставлен в очередь, когда / если поток будет перезапущен.
    Если объект QThread удален, obj->thread() возвращает 0, поэтому я предполагаю, что это будет эквивалентно вызову obj->moveToThread(0) и согласно документации:

    Если targetThread равен нулю, вся обработка событий для этого объекта и его дочерних элементов прекращается.

  3. quit() завершает цикл обработки событий, затем из потока выдается сигнал finished(), и поток завершается.
    Таким образом, даже когда вы получаете сигнал finished(), вы не должны предполагать, что поток еще не закончен. Вы можете использовать QThread::wait из основного потока, после того как вы получите этот сигнал, чтобы убедиться, что.
    Если поток находится в состоянии завершения, деструктор QThread уже вызывает wait, так что вы можете безопасно удалить поток после сигнала finished()deleteLater(), чтобы быть еще безопаснее).

0 голосов
/ 16 марта 2012

1.Что произойдет, если я продолжу использовать someFunct() даже после того, как издаю over() из someFunct()?Это неопределенное поведение или нормальное?

Поскольку вы используете прямые соединения, излучение over вызовет непосредственно функцию quit, , которая останавливает цикл обработки событий и возвращается из exec вметод запуска потока. Это означает, что someFunct() не завершит свое выполнение, и объекты внутри него либо потеряны, либо находятся в частично измененном состоянии.

2.С каким потоком теперь будет связан объект (в то время как остальная часть кода после выполнения over () все еще выполняется в someFunct)?

Как уже говорилось ранее somefunct не завершит свое выполнение.Но я считаю, что любые объекты, связанные с этим потоком, останутся таковыми.Я говорю, что верю, потому что нигде нет твердого утверждения, но оно имеет смысл больше всего. Как уже упоминалось в документе , для того, чтобы эти объекты отправляли или получали события, поток должен быть снова запущен ....

3.После того, как слот quit () для th выполнен, можно ли предположить, что поток действительно завершился, или я должен дополнительно подключить сигнал Finish () th к некоторому слоту, чтобы быть абсолютно уверенным?1028 * завершает цикл обработки событий и возвращает туда, где был вызван exec().

Обратите внимание, что объект Qthread не является потоком.так что пока вы не введете exec(), это основной поток, который работает ... Как и основной поток, который запускается после exec.

В любом случае, это несколько замечательных вопросов ...

...