Название: Многократный вызов функции из потока Отправлено: voltron от Апрель 19, 2011, 14:34 Есть некая функция, выполняющая длительную операцию. Хочу вынести ее в отдельный поток, чтобы на время выполнения не блокировался интерфейс. Т.к. эта функция вызывается несколько раз с разными входными параметрами, то хотелось бы реализовать все так, чтобы можно было создать поток один раз и вызывать функцию по необходимости (в остальное время поток должен спать).
Посмотрел в Qt Assistant, похожий функционал есть в Mandelbrot Example. Попробовал реализовать и вот что получилось extractorthread.h Код: class ExtractorThread : public QThread extractorthread.cpp Код: ExtractorThread::ExtractorThread( QWidget* parent = 0 ) Правильный ли это подход, не упустил ли я что-либо важное из виду? С многопоточностью практически не работал, поэтому прошу совета. И еще один вопрос. В функцию передаются указатели на классы-наследники QObject. Нужно ли на время доступа к методам этих классов защищать их мьютексом? Название: Re: Многократный вызов функции из потока Отправлено: merke от Апрель 19, 2011, 14:54 В общем тебе нужно следующее.
Создать не функцию в потоке, а слот с необходимыми параметрами. А у себя уже создай сигнал с такими же параметрами. Свой сигнал свяжи со слотом из потока. Когда необходимо передать данные потоку емить свой сигнал. Аналогичным способом получай данные из потока. Там емить сигнал с результирующими данными. В главном потоке связывай тот сигнал со своим слотом в главном потоке и обрабатывай данные. Из этого всего следует, что ни когда не вызывай напрямую функцию в потоке. Теперь ещё: когда будешь создавать объект своего класса: Код: ExtractorThread *myThread = new ExtractorThread(); Делай Код: myThread->moveToThread(myThread); Название: Re: Многократный вызов функции из потока Отправлено: mutineer от Апрель 19, 2011, 15:10 Теперь ещё: когда будешь создавать объект своего класса: Код: ExtractorThread *myThread = new ExtractorThread(); Делай Код: myThread->moveToThread(myThread); Не стоит мувать тред в самого себя. Уж лучше создать свой класс наследником QObject и перемещать его в обычный QThread Название: Re: Многократный вызов функции из потока Отправлено: Igors от Апрель 19, 2011, 15:14 Есть некая функция, выполняющая длительную операцию. Хочу вынести ее в отдельный поток, чтобы на время выполнения не блокировался интерфейс. Т.к. эта функция вызывается несколько раз с разными входными параметрами, то хотелось бы реализовать все так, чтобы можно было создать поток один раз и вызывать функцию по необходимости (в остальное время поток должен спать). Здесь не видно никакой необходимости что-то защищать (конфликтов нет), проще сделать как сказал Александр (с учетом moveToThread что многократно здесь обсуждалось). Если главная нитка хочет прервать вычисления, достаточно если она просто взведет mStop. Это также не требует мутексов, просто надо иметь ввиду: рабочая нитка не прервется немедленно, она должна увидеть mStop = true, закончить вычисления и отэмитить сигнал главной Посмотрел в Qt Assistant, похожий функционал есть в Mandelbrot Example. Попробовал реализовать и вот что получилось И еще один вопрос. В функцию передаются указатели на классы-наследники QObject. Нужно ли на время доступа к методам этих классов защищать их мьютексом? Вы собираетесь менять их из главной нитки в процессе вычислений? Нет (судя по Вашему коду). Значит защита не требуетсяНазвание: Re: Многократный вызов функции из потока Отправлено: voltron от Апрель 19, 2011, 17:13 Создать не функцию в потоке, а слот с необходимыми параметрами. Спасибо. Значит у меня должно быть что-то вроде такого, да?А у себя уже создай сигнал с такими же параметрами. Свой сигнал свяжи со слотом из потока. Когда необходимо передать данные потоку емить свой сигнал. Аналогичным способом получай данные из потока. Там емить сигнал с результирующими данными. В главном потоке связывай тот сигнал со своим слотом в главном потоке и обрабатывай данные. Код: class ExtractorThread : public QThread Данные назад в основную нитку передаются косвенным образом, примерно так Код: vectorProvider* provider = outLayer->provider(); Из этого всего следует, что ни когда не вызывай напрямую функцию в потоке. Т.е. пример Mandelbrot Example из Assistant, где есть вызов функции из потока не совсем правильный и так лучше не делать?Название: Re: Многократный вызов функции из потока Отправлено: Igors от Апрель 19, 2011, 17:40 Код: public slots: Из этого всего следует, что ни когда не вызывай напрямую функцию в потоке. Т.е. пример Mandelbrot Example из Assistant, где есть вызов функции из потока не совсем правильный и так лучше не делать?Название: Re: Многократный вызов функции из потока Отправлено: CL0NE от Апрель 19, 2011, 20:18 Цитировать Если Вы сделаете stop через сигнал/слот, то он может быть принят рабочей ниткой только после предыдущего (extractData), т.е. такой stop ничего не прерывает. Поэтому stop надо делать напрямую Дополнение: processEvents/свой eventloop в extractData, тогда можно и слотом |