![]() |
|
![]() ![]() ![]() |
|
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 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(); , то где и как его потом удалять? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
maric2000, делай умный указатель и храни его где-нибудь так, чтобы он уничтожился раньше, чем поток.
|
|||
|
||||
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 2.10.2009 Репутация: нет Всего: нет |
В моей программе объект потока и Worker создаются в конструкторе MainWindow и существуют в течении всего времени работы программы. Поэтому думаю умный указатель тут не нужен. Просто в деструкторе MainWindow нужно средствами синхронизации сперва завершить Worker, затем поток. Видимо все же проще унаследовать QThread, и в его методе run() создавать объект Worker. Тогда и проблем с удалением Worker не возникает. Просто в статье утверждалось что первый вариант лучше. |
|||
|
||||
borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 48 Всего: 135 |
нет ? -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 2.10.2009 Репутация: нет Всего: нет |
Спасибо, вроде то что нужно.
Только смущает вызов worker->finishWork(), т.к. это прямой вызов ф-ии из другого потока. Может вызов этой ф-ии заменить на : connect( this, SIGNAL( signalFinishWork() ), & worker, SLOT( finishWork() ) ); emit signalFinishWork(); ? Добавлено через 12 минут и 41 секунду опечатка в предыдущем посте:
|
|||
|
||||
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 2.10.2009 Репутация: нет Всего: нет |
И все же непонятно что происходит с динамическим объектом после вызова moveToThread (worker->moveToThread(&thread);). А интересно узнать.
Родителем остается MainWindow, но выполняется он в потоке thread, поэтому вызывать его функции из MainWindow нельзя (без средств сихронизации). Или как? Данный вопрос не освещен ни в документации Qt, ни в учебниках по Qt. По крайней мере я не нашел. Добавлено через 3 минуты и 1 секунду Поправлюсь: MainWindow не является родителем, просто в его конструкторе создается worker |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
maric2000, когда ты создаешь объект наследник QObject, то все операции с сигналами и слотами ассоциируются с создающим потоком. Но ты хочешь, чтобы объект работал в другом потоке. Для этого, необходимо произвести переассоциацию, что и делает moveToThread.
|
|||
|
||||
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 2.10.2009 Репутация: нет Всего: нет |
Что вы имеете ввиду под переассоциацией?
Добавлено через 9 минут и 14 секунд То, что "объект обрабатывает события, которые попадают в цикл обработки событий, того потока, которому принадлежит" я уже понял. |
|||
|
||||
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 2.10.2009 Репутация: нет Всего: нет |
Т.е. moveToThread меняет принадлежность к потоку объекта и после завершения потока его необходимо удалить (если объект был создан динамически) или не использовать (если объект - стековый). А все правильно понял?
|
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
||||
|
||||
maric2000 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 11 Регистрация: 2.10.2009 Репутация: нет Всего: нет |
Спасибо! Все ясно.
Т.е. после завершения потока, в котором выполнялся worker, единственно доступной функцией по отношению к нему остается delete? Можно ли в finishWork() объкта worker вызывать deleteLater(), чтобы не писать delete worker в основном потоке? Например в finishWork() вызвать moveToThread(QApplication::instance()->thread()) чтоб вернуть объект обратно? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
maric2000, а кто запрещает?
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |