QObject::deleteLater через QThread
Я ищу решение для планирования удаления объекта между потоками. Документы о том, как deleteLater
вести себя не совсем понятно. Могу ли я вызвать эту функцию в потоке, который не является владельцем объекта?
Например, объект X принадлежит потоку A, а в потоке B I хотел бы удалить объект X. Поскольку объект может быть внутри обработки событий в данный момент (в потоке A), я не могу безопасно удалить его, пока он не вернется в цикл обработки сообщений. Если я позвоню deleteLater
однако из потока B документы, похоже, указывают, что он будет удален, как только поток B вернется в цикл обработки сообщений.
В настоящее время я использую подход, из-за которого сигнал генерируется в потоке А, который подключен к слоту, который вызывает deleteLater
, Мне интересно, если есть, возможно, более простой способ сделать это - если я могу просто позвонить deleteLater
из любой темы.
3 ответа
Глядя на код Qt 4 и код Qt 5, deleteLater()
просто вызывает QCoreApplication::postEvent()
который явно объявлен потокобезопасным. Таким образом, должно быть хорошо просто позвонить напрямую. Поскольку очередь событий обрабатывается в потоке владельца объекта, удаление будет происходить в потоке A.
Если вы хотите полностью полагаться на документированное поведение, просто используйте postEvent()
,
В то время как deleteLater()
сам по себе небезопасен, вы можете вызвать его в object
"s threadA
с мета-вызовом:
metaObject()->invokeMethod(object, "deleteLater", Qt::QueuedConnection);
Тогда это будет безопасно.
deleteLater()
означает только, что объект будет удален после обработки всех сигналов / слотов в текущем цикле событий (т. е. ThreadB).
Так что, если никакие другие слоты не нуждаются в ObjectX в ThreadB, это эквивалентно обычному delete
,
Можете ли вы удалить объект или нет, и как он будет обрабатываться в ThreadA, зависит от логики вашего приложения.
Если ObjectX является основным объектом потока, отправка quit()
Сигнал к ThreadA - это путь.