Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt] как и где удалять объект после moveToThread, как и где потом удалять объект 
V
    Опции темы
maric2000
Дата 14.12.2012, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



У меня вопрос о принадлежности объектов потока.
Информацию о "Хорошем способе" проектирования работы с потоком почерпнул отсюда http://habrahabr.ru/post/115835/ . 

Пример из статьи:
class Worker : public QObject
{
    Q_OBJECT
 
public slots:
    void doWork() {
        /* ... */
    }
}; 
/* ... */
QThread thread;
Worker worker;
connect(obj, SIGNAL(workReady()), &worker, SLOT(doWork()));
worker.moveToThread(&thread);
thread.start();

Объект который должен выполнятся в потоке, мы отправляем выполнятся в поток методом moveToThread.
Вопрос такой: кому принадлежит и где удаляется объект Worker после worker.moveToThread(&thread)?

Если объект Worker создается динамически
Worker *worker = new Worker;
connect(obj, SIGNAL(workReady()), worker, SLOT(doWork()));
worker->moveToThread(&thread);
thread.start();
, то где и как его потом удалять?
PM MAIL   Вверх
bsa
Дата 14.12.2012, 10:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



maric2000, делай умный указатель и храни его где-нибудь так, чтобы он уничтожился раньше, чем поток.
PM   Вверх
maric2000
Дата 14.12.2012, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



Цитата(bsa @  14.12.2012,  10:52 Найти цитируемый пост)
maric2000, делай умный указатель и храни его где-нибудь так, чтобы он уничтожился раньше, чем поток. 

В моей программе объект потока и Worker создаются в конструкторе MainWindow и существуют в течении всего времени работы программы.
Поэтому думаю умный указатель тут не нужен. Просто в деструкторе MainWindow нужно средствами синхронизации сперва завершить Worker, затем поток.

Видимо все же проще унаследовать QThread, и в его методе run() создавать объект Worker. Тогда и проблем с удалением Worker не возникает.
Просто в статье утверждалось что первый вариант лучше.
PM MAIL   Вверх
borisbn
Дата 14.12.2012, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 48
Всего: 135



Цитата(maric2000 @  14.12.2012,  13:25 Найти цитируемый пост)
Просто в деструкторе MainWindow нужно средствами синхронизации сперва завершить Worker, затем поток.

Код
connect( worker, SIGNAL( onFinish() ), & thread, SLOT( quit() ) );
worker->finishWork();
thread.wait();
delete worker;


нет ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
maric2000
Дата 17.12.2012, 06:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



Спасибо, вроде  то что нужно.
Только смущает вызов worker->finishWork(), т.к. это прямой вызов ф-ии из другого потока.

Может вызов этой ф-ии заменить на :

connect( this, SIGNAL( signalFinishWork() ), & worker, SLOT( finishWork() ) );
emit signalFinishWork();

?

Добавлено через 12 минут и 41 секунду
опечатка в предыдущем посте:
Код

connect( this, SIGNAL( signalFinishWork() ), worker, SLOT( finishWork() ) );

PM MAIL   Вверх
maric2000
Дата 17.12.2012, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



И все же непонятно что происходит с динамическим объектом после вызова moveToThread (worker->moveToThread(&thread);). А интересно узнать.
Родителем остается MainWindow, но выполняется он в потоке thread, поэтому вызывать его функции из MainWindow нельзя (без средств сихронизации). Или как?
Данный вопрос не освещен ни в документации Qt, ни в учебниках по Qt. По крайней мере я не нашел.

Добавлено через 3 минуты и 1 секунду
Поправлюсь: MainWindow не является родителем, просто в его конструкторе создается worker 
PM MAIL   Вверх
bsa
Дата 17.12.2012, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



maric2000, когда ты создаешь объект наследник QObject, то все операции с сигналами и слотами ассоциируются с создающим потоком. Но ты хочешь, чтобы объект работал в другом потоке. Для этого, необходимо произвести переассоциацию, что и делает moveToThread. 
PM   Вверх
maric2000
Дата 17.12.2012, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



Что вы имеете ввиду под переассоциацией?

Добавлено через 9 минут и 14 секунд
То, что "объект обрабатывает события, которые попадают в цикл обработки событий, того потока, которому принадлежит" я уже понял.
PM MAIL   Вверх
maric2000
Дата 17.12.2012, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



Т.е. moveToThread меняет принадлежность к потоку объекта и после завершения потока его необходимо удалить (если объект был создан динамически) или не использовать (если объект - стековый). А все правильно понял? 
PM MAIL   Вверх
bsa
Дата 17.12.2012, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



Цитата(maric2000 @  17.12.2012,  13:48 Найти цитируемый пост)
после завершения потока его необходимо удалить (если объект был создан динамически) или не использовать (если объект - стековый). А все правильно понял?  
Да. Ну еще можно сделать moveToThread на незавершившийся поток.

PM   Вверх
maric2000
Дата 17.12.2012, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 2.10.2009

Репутация: нет
Всего: нет



Спасибо! Все ясно.
Т.е. после завершения потока, в котором выполнялся worker, единственно доступной функцией по отношению к нему остается delete?
Можно ли в finishWork() объкта worker вызывать deleteLater(), чтобы не писать delete worker в основном потоке?

Цитата(bsa @  17.12.2012,  13:35 Найти цитируемый пост)
Ну еще можно сделать moveToThread на незавершившийся поток

Например в finishWork() вызвать moveToThread(QApplication::instance()->thread()) чтоб вернуть объект обратно? 
PM MAIL   Вверх
bsa
Дата 17.12.2012, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 24
Всего: 196



maric2000, а кто запрещает?
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.1003 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.