Sleep we threadzie zasypia za bardzo :/

Witam,
przerabialem program z qtpythona na qtruby. Z interfejsem w qt poszlo gladko, z reszta troche mniej, ale wlasciwie wszystko skonczone. Problem mam ze stoperem. Chcialem go zrobic tak jak w tuzinie innych programow w 5 innych jezykach, tj. osobny thread, ktory zasypia co 1 sekunde i zmienia wartosc zegara.

W moim ruby-wykonaniu wyglada to tak:
@thread = Thread.new { loop { countTime; sleep(1) } }

Problem w tym, ze dziala to fatalnie! Timer zamarza i czeka az zamacham myszka przed ekranem (o dziwo to pomaga, nie mowcie, ze GUI sie nie repaintuje na czas?! O_O). Czy ktos moze mi wytlumaczyc, czemu teoretycznie poprawny kod dziala na Threada, nie jakby mial na chwile przysnac, ale jakby dostal narkoze? :confused:

EDIT:
Ba, natrafilem na cos o wiele gorszego. Gdy stoper dojedzie do zera, thread powinien o tym poinformowac watek glowny (wyskakuje popup dialog i zmeinia sie pare zmiennych) i grzecznie dac sie zabic. Problem w tym, ze mimo prob z Thread.kill(ten_watek), ten_watek.stop i zwyklego konczenia petli, tkora potrzymywala rzekomy watek, ciagle otrzymuje jakze trefny komunikat:

QObject::killTimer: timers cannot be stopped from another thread

Coz na to poradzic? O_o

Nie wiem jak to jest w QT, ale w Javie jak robiłeś coś w osobnym wątku i chciałeś z niego zmieniać coś w GUI, to trzeba było użyć specjalnego wywołania, coś w stylu asyncExec, czy jakoś tak. Być może tutaj sytuacja jest podobna?

Niestety tak. Poczytaj dokładnie dokumentację QTRuby. Niestety niektóre calle do QT są blokujące. Wątki w Ruby to nie są prawdziwe (tzw. systemowe) wątki tylko tzw. “zielone” wątki zarządzane przez interpreter. W momencie kiedy wyskakujesz do porcji QT napisanej w C++ cały interpreter przestaje działać (w efekcie także wątki).
Wskazuje na to fakt że program zaczyna działać w momencie gdy machasz myszką. Najprawdopodobniej masz pętle która obsługuje eventy, i wywołuje Ruby. W momencie kiedy system wchodzi do pętli i “blokuje” w oczekiwaniu na kolejne zdarzenie, Ruby przestaje działać.

Musisz uruchomić interpreter Ruby w osobnym wątku systemowym, a GUI w QT w innym.