2009-09-06 14 views
23

Główna (główna funkcja tam) wątek mojego programu jest zarezerwowany dla zadań innych niż GUI. Wywołuje szereg długich funkcji obliczeniowych. Wszystkie implementowane GUI pracują w oddzielnych wątkach.Jak sprawić, aby Qt działało, gdy główny wątek jest zajęty?

Mam zamiar wdrożyć jeszcze jeden GUI za pomocą Qt. Qt documentation mówi, że wszystkie zadania związane z GUI powinny być wykonywane w głównym wątku. W moim przypadku wstawianie sporadycznych wywołań QCoreApplication :: processEvents() w wątku głównym byłoby praktycznie bezużyteczne z powodu dużych opóźnień między nimi.

Czy istnieje sposób na pokonanie tego ograniczenia Qt? Czy w głównym wątku programu Qt nie można zrobić czegoś, co nie jest GUI?

+4

Dlaczego nie możesz wykonać swojej pracy nad innym wątkiem? – Kornel

+1

Tylko ze względów historycznych. Refaktoryzacja będzie bolesna, dlatego postanowiłem przeprowadzić pewne badania, jeśli można tego uniknąć. – Basilevs

Odpowiedz

20

Nie, powinieneś wykonywać swoje obliczenia w osobnym wątku. Jak już wspomniałeś, w serwisie QCoreApplication::processEvents() dostępne jest obejście problemu, ale wygląda na to, że nie możesz wykonać tej pracy.

Jeśli nie chcesz wykonywać całej pracy związanej z konfigurowaniem QThread i przenoszeniem całego kodu, może się okazać, że funkcja QtConcurrent::run jest przydatna - pozwala na uruchamianie funkcji asynchronicznie.

Kilka wskazówek: Powinieneś starać się, aby twój wątek główny (GUI) był jak najmniejszy. Duże ilości operacji IO lub obliczeń powinny być wykonywane asynchronicznie przy użyciu QtConcurrent :: run lub uruchamiać w oddzielnym QThread. W zależności od złożoności twojego kodu, możesz być w stanie uciec z metodą QtConcurrent.

+1

Nie widzę dużej korzyści z używania QtConcurrent :: run() zamiast QThread. W rzeczywistości jest to więcej pracy w ten sposób. Trzymaj się QThread, jego dużo łatwiejsze do wdrożenia –

+2

To zależy od tego, co robisz i jak zbudowany jest twój program. Jeśli potrzebujesz stałego wątku, który zawsze musi być uruchomiony, użyj QThread. Jeśli potrzebujesz wielu małych (często niezależnych) zadań do uruchomienia, a nie obchodzi cię, które z nich są uruchomione o której godzinie, użyj QtConcurrent. – Thomi

+0

Tak, zgadzam się, że mogłem być trochę trudny w tym ... jak mówisz, zależy to od tego, czego potrzebujesz. –

4

Najlepiej odciążyć długie obliczenia na inne wątki, aby główny wątek GUI pozostał elastyczny. W starym szkolnym, jednoprocesowym sposobie robienia rzeczy byłoby upewnienie się, że twoje obliczenia nigdy nie będą działały zbyt długo bez obsługi zdarzeń z GUI, ale nie skalują się do wielu rdzeni.

Na szczęście Qt ma doskonałe threading support. W przeszłości musielibyśmy wdrożyć własny system, np. Do zadań związanych z pulą wątków, używając QThread, QMutex, itp., Ale ostatnie wydania Qt ułatwiały pracę dzięki wyższym poziomom abstrakcji, takim jak QThreadPool, QtConcurrent::run i QFuture. .

+1

Dlaczego nie używać połączeń QObject między wątkami? –

0

Nie wiem, jak sprawy pójdą, jeśli wywołasz QApplication :: exec() z innego wątku, który następnie staje się twoim wątkiem GUI. Tylko pomysł.

(Daj nam znać, czy zadziała, byłoby ciekawie ...)

+0

Dlaczego chcesz to zrobić?Jeśli musisz wykonać pracę, aby wypluć swój kod i uruchomić połowę z niego w innym wątku, równie dobrze możesz to zrobić poprawnie ... czy też coś mi brakuje? – Thomi

+0

Nie polecam, po prostu dawam wskazówkę, jak osiągnąć dokładnie to, co zadał OP. Powodem mogą być inne biblioteki, które wymagają rzeczy wykonanych w głównym wątku. (IIRC, OpenSG 1.x wymagało renderowania i ładowania w tym samym wątku, więc skończyło się ciężkim rysowaniem OpenGL w głównym wątku (ponieważ wczytaliśmy całą grafikę do tego wątku). , ale tak to poszło. (Naprawiono to w 2.x, IIRC) – Macke

+1

Możesz to zrobić, zrobiliśmy to za pomocą prostej aplikacji i zadziałało, ale kiedy nasz program się kończy, dostajemy nieprawidłowy błąd free() lub podwójny darmowy() błąd: – dgrant

Powiązane problemy