| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt] как и где удалять объект после moveToThread |
| Автор: maric2000 14.12.2012, 08:25 |
| У меня вопрос о принадлежности объектов потока. Информацию о "Хорошем способе" проектирования работы с потоком почерпнул отсюда 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 14.12.2012, 10:52 |
| maric2000, делай умный указатель и храни его где-нибудь так, чтобы он уничтожился раньше, чем поток. |
| Автор: borisbn 14.12.2012, 15:33 | ||||
нет ? |
| Автор: maric2000 17.12.2012, 06:35 | ||
| Спасибо, вроде то что нужно. Только смущает вызов worker->finishWork(), т.к. это прямой вызов ф-ии из другого потока. Может вызов этой ф-ии заменить на : connect( this, SIGNAL( signalFinishWork() ), & worker, SLOT( finishWork() ) ); emit signalFinishWork(); ? Добавлено через 12 минут и 41 секунду опечатка в предыдущем посте:
|
| Автор: maric2000 17.12.2012, 08:41 |
| И все же непонятно что происходит с динамическим объектом после вызова moveToThread (worker->moveToThread(&thread);). А интересно узнать. Родителем остается MainWindow, но выполняется он в потоке thread, поэтому вызывать его функции из MainWindow нельзя (без средств сихронизации). Или как? Данный вопрос не освещен ни в документации Qt, ни в учебниках по Qt. По крайней мере я не нашел. Добавлено через 3 минуты и 1 секунду Поправлюсь: MainWindow не является родителем, просто в его конструкторе создается worker |
| Автор: bsa 17.12.2012, 11:18 |
| maric2000, когда ты создаешь объект наследник QObject, то все операции с сигналами и слотами ассоциируются с создающим потоком. Но ты хочешь, чтобы объект работал в другом потоке. Для этого, необходимо произвести переассоциацию, что и делает moveToThread. |
| Автор: maric2000 17.12.2012, 12:23 |
| Что вы имеете ввиду под переассоциацией? Добавлено через 9 минут и 14 секунд То, что "объект обрабатывает события, которые попадают в цикл обработки событий, того потока, которому принадлежит" я уже понял. |
| Автор: maric2000 17.12.2012, 12:48 |
| Т.е. moveToThread меняет принадлежность к потоку объекта и после завершения потока его необходимо удалить (если объект был создан динамически) или не использовать (если объект - стековый). А все правильно понял? |
| Автор: bsa 17.12.2012, 13:35 | ||
|
| Автор: maric2000 17.12.2012, 14:12 |
| Спасибо! Все ясно. Т.е. после завершения потока, в котором выполнялся worker, единственно доступной функцией по отношению к нему остается delete? Можно ли в finishWork() объкта worker вызывать deleteLater(), чтобы не писать delete worker в основном потоке? Например в finishWork() вызвать moveToThread(QApplication::instance()->thread()) чтоб вернуть объект обратно? |
| Автор: bsa 17.12.2012, 16:17 |
| maric2000, а кто запрещает? |