Dużo przemyślałem i przeczytałem wiele artykułów zanim zadaję to pytanie tutaj. Żaden z artykułów nie dał mi właściwej odpowiedzi.QThread finished() connected to deletelater z QObject
http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
Pracownik obiekt ma powinowactwo nowej nici.
1> Pracownik zakończył sygnał wywołaj quit() na wątku. Spowoduje to zakończenie pętli zdarzeń wątku i zainicjowanie wątku zakończonego sygnałem.
2> Sygnał zakończony przez pracownika jest połączony z robotem deleteLater(). Zgodnie z instrukcją deleteLater()
** Planuje ten obiekt do usunięcia. Obiekt zostanie usunięty, gdy sterowanie powróci do pętli zdarzeń. Jeśli pętla Impreza> nie działa
kiedy ta funkcja jest wywoływana (np deleteLater() jest wywoływana na obiektu przed QCoreApplication :: exec()), obiekt zostanie usunięty po uruchomieniu pętli zdarzenia.
Należy zauważyć, że wprowadzenie i wyjście z nowej pętli zdarzeń (np. Poprzez otwarcie modalnego okna dialogowego) nie spowoduje odroczonego usunięcia; aby obiekt mógł zostać usunięty, kontrola musi wrócić do pętli zdarzeń, z której wywołano metodę deleteLater().
Uwaga: To można bezpiecznie wywołać tę funkcję więcej niż jeden raz; kiedy pierwszy odroczony wydarzenie delecja jest dostarczany wszelkie toczące się wydarzenia dla obiektu są usunięte z kolejki zdarzeń. **
Więc gdy nie ma eventloop, ponieważ wątek jest już wyjściu i to już podniesione gotowy sygnał i już nie będziemy zaczynać ponownie tego samego wątku. W takim przypadku funkcja deleteLater() nigdy nie będzie obsługiwana, ponieważ pętla zdarzeń nie istnieje, a obiekt roboczy nie zostanie w ogóle usunięty. Czy to nie powoduje wycieku pamięci.?
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
Jeśli uważamy, że zamiana dwóch wierszy będzie rozwiązać ten problem, to mam jeszcze jedno pytanie. QT wyraźnie stwierdza, że kolejność wywoływania gniazd w momencie emisji sygnału jest nieokreślona.
Istnieje kilka komentarzy w powyższym łączu artykułu. Nawet autor nie był w stanie odpowiedzieć na pytanie, całkowicie
nie możesz usuwać pracownika w stworzonym wątku obiektu. ponieważ został już przeniesiony do wątku za pomocą moveToThread. Czy możesz to wyjaśnić? – Srikan
Polecam również przypisanie rodzica do 'QThread'.Ponieważ instancja 'QThread' jest częścią wątku, w którym została utworzona (w przeciwieństwie do wszelkich obiektów, które zostały przeniesione do niej lub jej metoda' run() '), jest całkowicie bezpieczne wykonywanie' thread = new QThread (this); 'jeśli' thread' ma być częścią innej klasy. Generalnie powinieneś unikać wywoływania 'delete', jeśli istnieje lepsze rozwiązanie nie-ręczne. Nawet w standardowym C++ masz inteligentne wskaźniki, a co nie, które ponoszą ciężar ręcznego oczyszczania ramion. – rbaleksandar