2012-03-09 17 views
5

Szukam rozwiązania zaplanować usunięcie obiektu przez wątki. Dokumenty o tym, jak zachowują się deleteLater, nie są całkiem jasne. Czy mogę wywołać tę funkcję w wątku, który nie jest właścicielem obiektu?QObject :: deleteLater przez QThread

Na przykład obiekt X jest własnością wątku A, a w wątku B chciałbym, aby obiekt X został usunięty. Ponieważ obiekt może być w trakcie przetwarzania zdarzenia (w wątku A), nie mogę go bezpiecznie usunąć, dopóki nie wróci do pętli wiadomości. Jeśli zadzwonię pod numer deleteLater z wątku B, to jednak dokumenty będą wskazywać, że zostaną usunięte, gdy tylko wątek B powróci do pętli wiadomości.

Obecnie stosuję podejście polegające na posiadaniu sygnału emitowanego w wątku A, który jest podłączony do gniazda, które wywołuje deleteLater. Zastanawiam się, czy jest być może łatwiejszy sposób to zrobić - jeśli rzeczywiście mogę po prostu zadzwonić deleteLater z dowolnego wątku.

+0

W Qt można zmienić, który wątek jest właścicielem obiektu. Czy to ci pomoże? – sashoalm

+0

W ten sposób obiekt dostaje się do wątku. –

Odpowiedz

0

deleteLater() oznacza tylko, że obiekt zostanie usunięty po tym, jak wszystkie sygnały/szczeliny w bieżącej pętli zdarzeń (tj. ThreadB) zostały potraktowane.

Tak więc, jeśli żaden inny slot nie wymaga ObjectX w ThreadB, jest to odpowiednik zwykłego delete.

Niezależnie od tego, czy możesz usunąć obiekt, czy nie i jak będzie on obsługiwany w wątku, zależy to od logiki aplikacji.

Jeśli obiekt ObjectX jest głównym obiektem wątku, należy przesłać sygnał quit() do ThreadA.

+0

Będzie wiele takich obiektów, wątek jest odrębnym obiektem. Potwierdzasz jednak, że deleteLater rzeczywiście ma miejsce w bieżącym wątku (w związku z tym nie jest bezpieczny dla mojego użycia). –

+0

@ edA-qamort-ora-y Zależy to od wersji Qt, której używasz. Zobacz komentarz 'Lol4t0' poniżej twojego pytania. –

6

deleteLater() Chociaż nie jest bezpieczna, można wywołać go w object „s threadA z meta rozmowy:

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

Wtedy będzie to bezpieczne.

+0

Obawiam się, że dokumenty mówią tylko o "pętli głównego zdarzenia" dla połączenia w kolejce tutaj (zupełnie różni się to od tego, jak zwykle działa kolejka połączeń). Czy jest to po prostu błąd dokumentu, czy rzeczywiście będzie to normalny sygnał wciśnięty w drugi wątek? –

+0

@ edA-qamort-ora-y, Cóż, wygląda na to, że to błąd dokumentacji, a ja usunąłem obiekty z takim kodem, ale podczas pobierania kodu źródłowego Qt właśnie znalazłem to bezpośrednie wywołanie 'deleteLater' tak bezpieczne, jak meta zadzwoń, więc w obecnej realizacji bezpośrednie działanie połączeń i przyszłe wersje mogą być zaskakujące w obu przypadkach. – Lol4t0

+0

Śledziłem również kod źródłowy, a on deleteLater właśnie opublikuje wydarzenie i śledzi, czy opublikowane zdarzenia będą zawsze wysyłane do właściciela wątku odbiorcy. Argh! Dlaczego doktorzy nie mogli powiedzieć tego samego, więc nie martwiłbym się tym ...:( –

5

Patrząc na Qt 4 code i Qt 5 code, deleteLater() po prostu wywołuje QCoreApplication::postEvent(), który jest jawnie zadeklarowany wątek bezpieczne. Powinno być dobrze, po prostu zadzwoń bezpośrednio. Ponieważ kolejka zdarzeń jest przetwarzana w wątku właściciela obiektu, usunięcie nastąpi w wątku A.

Jeśli chcesz całkowicie polegać na udokumentowanym działaniu, po prostu użyj postEvent().

Powiązane problemy