Russian Qt Forum

Qt => Общие вопросы => Тема начата: uriel от Июнь 08, 2009, 23:26



Название: Корректная остановка потока
Отправлено: uriel от Июнь 08, 2009, 23:26
Решил на досуге побаловаться с PyQt и внезапно обнаружил своё непонимание некоторых концептуальных вещей. :)
Есть банальная ситуация: кнопочка запускает поток, в котором начинает крутиться одна единственная "тяжёлая" функция. По другой кнопочке её выполнение должно прерваться.
Способ с очередью сообщений и quit() вроде бы не подходит, потому как exec() занимает основной поток управления, а функция как бы тоже должна где-то крутиться...
Решил попробовать сделать влоб - terminate(). В 80% случаев оно работает, но в оставшихся 20% - интерфейс становится неотзывчивым и складывается впечатление, что ломается основная очередь событий приложения. Ну ладно, в документации и написано, что использование этой функции крайне не рекомендуется.
Сначала погрешил на биндинг, но, попробовав переписать на C++, с удивлением обнаружил схожее поведение. Забавно, что под Windows terminate() иногда вообще не срабатывает и поток продолжает выполняться даже после её вызова (но это только с PyQt, на плюсах на проверял).
А вопрос собственно такой: как вообще по-человечески можно решить подобную задачу? Заранее благодарен. ;)

P.S. Ах да, забыл сказать, что QtConcurrent в PyQt ещё не обернули.


Название: Re: Корректная остановка потока
Отправлено: Rcus от Июнь 09, 2009, 06:31
Нет общего способа корректно остановить выполнение функции и сохранить при этом целостность данных.
Вот что по этому поводу написано в доках KDE::ThreadWeaver:
Цитировать
virtual void ThreadWeaver::Job::requestAbort    (       )    [inline, virtual]


Abort the execution of the job.

Call this method to ask the Job to abort if it is currently executed. Please note that the default implementation of the method does nothing (!). This is due to the fact that there is no generic method to abort a processing Job. Not even a default boolean flag makes sense, as Job could, for example, be in an event loop and will need to create an exit event. You have to reimplement the method to actually initiate an abort action. The method is not pure virtual because users are not supposed to be forced to always implement requestAbort(). Also, this method is supposed to return immidiately, not after the abort has completed. It requests the abort, the Job has to act on the request.


Название: Re: Корректная остановка потока
Отправлено: BRE от Июнь 09, 2009, 08:25
Самая корректноя остановка потока, это когда он сам завершается.  :)
Т.е. использовать флаг, который проверяется в потоке и при необходимости его завершает.
На форуме несколько раз это обсуждалось, поищи.  ;)


Название: Re: Корректная остановка потока
Отправлено: uriel от Июнь 09, 2009, 09:55
Вот чёрт... виноват, действительно было, спасибо за наводку ;)