Obsługa 4 funkcji jednoczesnie

0

Witam,
Zetknąłem się z problemem synchronizacji kilku funkcji, chciałbym aby wykonywały się one równocześnie.

Konkretnie piszę program, który służy do obsługi skrzyżowania z sygnalizacją świetlną i chcę napisać coś na zasadzie "podgląd na żywo", czyli możliwość zobaczenia stanu sygnalizatorów. Całe skrzyżowanie pracuje w jakimś trybie, jest też możliwość ustawienia czasu (np. Światła zielonego) dla każdego sygnalizatory oddzielnie.

W przypadku, gdy czas jest dla wszystkich ten sam nie ma problemu, jak natomiast wymusić pracę każdego z osobna? Stworzyć 4 wątki, gdzie każdy będzie obsługiwać jeden z sygnalizatorów? Może jest inne rozwiązanie?

Pozdrawiam

1

W teorii jest to możliwe, ale zwykle rysowanie odbywa się w jednym wątku, wiec nie ma to sensu w takim przypadku. No chyba że masz jakieś urządzenia podpięte które są faktycznie równoległe.

Generalnie robi się pętlę w jednym wątku i w trakcie jej trwania aktualizowany jest każdy obiekt o odpowiednią deltę czasu która upłynęła od ostatniej aktualizacji. Wyświetlanie jest robione po takiej pętli. W teorii zmiana każdego z obiektów jest po kolei a nie razem, ale jako że taka pętla mieli nawet kilkaset razy na sekundę to wydaje się to płynne.

0

@krzysiek050: Czyli np, pobrać aktualny czas z systemu, po ustawieniu wartości obiektów zrobić switch lub zwykle ify, które kontrolują stanem każdego z sygnalizatorów?

1

Musisz stworzyć 1 wątek który posiada pętlę nieskończoną i 1 zmienną czasową lastUpdate. Po utworzeniu wątek powinien ustawić tą zmienną na obecny czas ( z dokładnością do mili lub micro sekund). W każdym uruchomieniu pętli powinno być:

  1. pobranie czasu currentTime i obliczenie dt czyli currentTime - lastUpdate. Wynik to np. liczba milisekund.
  2. aktualizuejsz lastUpdate = currentTime
  3. Odpalasz funkcję update z parametrem dt
  4. Odpalasz paintScene czy coś innego co ma Ci wypisać stan.

Niech semafor implementuje klasę abstrakcyjną Updatable która zawiera metodę wirtualną void update(double dt)'. Potem robisz listę wszystkich obiektów które mogą zmienić stan, czyli semafory, jakieś inne światła, pikacze, wszystko co jest Updatablei tam w pętli wywołujesz na każdym obiekcieupdate(dt);`

I teraz w samym semaforze masz metodę która będzie co jakiś czas wywoływana z czasem który minął od ostatniej aktualizacji. Na tej podstawie możesz zmieniać stany.

0

Powyższe rozwiązanie jest jest łatwe i skuteczne, ale bardzo nieoptymalne - wątek będzie obciążał 100% rdzenia, a rysowanie więcej fps niż ma monitor to marnowanie zasobów.
Rozwiązanie:

  • w najprostszym wypadku - jeśli dasz wątkowi co iterację pętli zasnąć na kilka ms, to zużycie CPU spadnie gdzieś w okolice zera. To będzie rozwiązanie skuteczne, łatwe i tylko trochę nieoptymalne.
  • jeśli potrzebujesz rysować kolejne klatki całkowicie odciążając procesor po narysowaniu każdej z nich, to użyj timera systemowego albo któregoś z jego bardziej precyzyjnych kolegów - http://stackoverflow.com/questions/5521146/what-is-the-best-most-accurate-timer-in-c.

Oczywiście w obu przypadkach i tak musisz obliczać deltę czasu tak jak napisał Krzysiek, bo żadnen z podanych sposobów nie gwarantuje równego interwału i czasem zależnei od implementacji albo animacja będzie zwalniać, albo będziesz gubić klatki.

0

Sygnalizatory zmieniają kolor raz na kilka minut więc wydaje mi się że odświeżanie co interacje pętli faktycznie może być obciazajace

1 użytkowników online, w tym zalogowanych: 0, gości: 1