2012-03-09 3 views
5

Я ищу решение для планирования удаления объекта по потокам. Документы о том, как ведут себя deleteLater, не совсем понятны. Можно ли вызвать эту функцию в потоке, который не является владельцем объекта?QObject :: deleteLater через QThread

Например, объект X принадлежит теме A, а в потоке B я хотел бы удалить объект X. Поскольку объект может находиться внутри обработки событий в данный момент (в Thread A), я не могу безопасно удалить его, пока он не вернется в цикл сообщения. Если я вызываю deleteLater из Thread B, однако документы, похоже, указывают, что он удалит, как только Thread B вернется в цикл сообщений.

В настоящее время я использую подход, излучаемый в потоке А, который прикреплен к слоту, который вызывает deleteLater. Мне интересно, есть ли более простой способ сделать это - если действительно, я могу просто позвонить deleteLater из любого потока.

+0

В Qt вы можете изменить, какой поток принадлежит объекту. Это поможет вам? – sashoalm

+0

Вот как объект попадает в поток. –

ответ

0

deleteLater() только означает, что объект будет удален после того, как будут обработаны все сигнальные/интервальные интервалы внутри текущего цикла событий (т. Е. ThreadB).

Итак, если никакие другие слоты не нуждаются в ObjectX в ThreadB, это эквивалентно простой delete.

Можно ли удалить объект или нет и как он будет обрабатываться в ThreadA, зависит от вашей логики приложения.

Если ObjectX является основным объектом потока, отправка сигнала quit() в ThreadA - это путь.

+0

Там будет много таких объектов, поток - это отдельный объект. Вы подтверждаете, что deleteLater действительно происходит только в текущем потоке (тем самым небезопасно для моего использования). –

+0

@ edA-qamort-ora-y Это зависит от версии Qt, которую вы используете. См. Комментарий 'Lol4t0' ниже вашего вопроса. –

6

deleteLater() В то время как это не безопасно само по себе, вы можете вызвать его в object «s threadA с мета вызова:

metaObject()->invokeMethod(object, "deleteLater", Qt::QueuedConnection); 

Тогда это будет безопасно.

+0

Я волнуюсь, что документы говорят только о «основной цепочке событий» для очереди в очереди (совсем не так, как обычно работает очередь). Является ли это просто ошибкой doc, будет ли это фактически как обычный сигнал, вдвинутый в другой поток? –

+0

@ edA-qamort-ora-y, похоже, это ошибка документации, и я удалил объекты с таким кодом, но, изучая исходный код Qt, я обнаружил, что прямой вызов 'deleteLater' столь же безопасен, как мета- вызова, поэтому в текущей реализации работа прямого вызова и поведение будущих версий могут быть неожиданными в обоих случаях. – Lol4t0

+0

Я также отслеживал исходный код, и он deleteLater просто публикует событие и отслеживает, что отправленные события всегда будут отправляться владельцу потока получателя. Argh! Почему не могли документы просто сказать то же самое, чтобы я не беспокоился об этом ...:( –

5

Глядя на Qt 4 code и Qt 5 code, deleteLater() просто вызывает QCoreApplication::postEvent(), который явно объявлен потокобезопасным. Таким образом, должно быть хорошо, просто называть это напрямую. По мере того, как очередь событий обрабатывается в потоке владельца объекта, удаление происходит в потоке A.

Если вы хотите полностью полагаться на документированное поведение, просто используйте postEvent().

Смежные вопросы