Autor Wątek: Sieć a wielowątkowość [Windows]  (Przeczytany 2047 razy)

Offline cziter15

  • Użytkownik

# Maj 30, 2013, 18:50:39
Hej,

Od kilku dni robię sobie projekcik shootera multiplayer. Jestem na poziomie biegania postacią po planszy. Mam gotowe systemy, ładowanie map... ale została sieć.

I teraz zastanawiam się jak dobrze zsynchronizować wątek renderujący + inne wątki z wątkiem sieciowym czekającym na pakiety.

Pomyślałem, że użyłbym sekcji krytycznych jednakże jest z tym pewien problem. W kodzie może być kilka różnych "ścieżek kodu", które będą chciały uzyskać dostęp powiedzmy do klasy środowiska. Przykładowo jakieś wątki fizyki, dźwięku...

Problem pojawi się na przykład w momencie, gdy podczas wywoływania dajmy na to destruktora klasy zarządzającej środowiskiem gry (sceny itd) otrzymam pakiet odwołujący się do właśnie niszczonego elementu (na przykład z informacjami o przemieszczeniu się gracza na planszy).

Nie mam zielonego pojęcia jak to dobrze zsynchronizować. Myślałem o zrobieniu jakiejś kolejki i obsługiwanie pakietów tylko z wątku renderingu... ale nie wiem...

Czekam na wasze sugestie, pomysły

Pozdrawiam,
Krzysiek

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Avaj

  • Użytkownik

  • +2
# Maj 30, 2013, 18:54:19
użyj funkcji select i rób wszystko na jednym wątku

Offline cziter15

  • Użytkownik

# Maj 30, 2013, 19:13:05
użyj funkcji select i rób wszystko na jednym wątku
Chciałbym jednak uniknąć robienia wszystkiego w jednym wątku. Problem może pojawić się gdy na przykład recv odbierze tylko część danych. Dałoby się to ominąć kolejką... Ale jednak wolę zaprzęgnąć do tego wątki.
« Ostatnia zmiana: Maj 30, 2013, 19:16:08 wysłana przez cziter15 »

Offline yarpen

  • Użytkownik

  • +1
# Maj 30, 2013, 19:39:04
Nie obsluguj pakietow od razu, skladuj je gdzies. Obsluguj albo na glownym watku albo pomiedzy sync pointami, kiedy wiesz, ze jest to bezpieczne.

Offline mwojt

  • Użytkownik

# Maj 30, 2013, 19:49:06
Wydaje mi się, że wątki tylko skomplikują program, recv powinno odebrać wszystkie dane, chyba że pakiety będą znacznej wielkości, możliwe że uruchamiasz recv raz na pętlę główną i się wszystko rozłazi, wystarczy uruchamiać recv w pętli dopóki przychodzą jakieś dane z czym jeden wątek powinien poradzić sobie bez problemu.

Offline Krzysiek K.

  • Redaktor
    • DevKK.net

# Maj 30, 2013, 20:02:19
użyj funkcji select i rób wszystko na jednym wątku
Popieram! :)

Cytuj
Wydaje mi się, że wątki tylko skomplikują program, recv powinno odebrać wszystkie dane, chyba że pakiety będą znacznej wielkości
Czas działania recv nie powinien znacząco zależeć od wielkości pakietu - w końcu jest on już pozbierany w pamięci i pozostaje tylko jego skopiowanie do aplikacji.

Offline magik6000

  • Użytkownik

# Maj 30, 2013, 20:08:13
A Wg mnie wątki nie gryzą(Ale trzeba uważać aby nie przegiąć). co do synchonizacji sekcji krytycznych to poczytaj o wynalazku zwanym 'mutex'
(generalnie chodzi o to, że tylko jeden wątek może 'mieć' dany mutex, a inne muszą na jego przejęcie czekać aż jego 'posiadacz' go odda). Poza mutexami jeszcze jest kilka fajnych mechanizmów synchronizacji, przy czym podpowiem, że jeśli byś się dokopał do tzw spinlock'ów to nawet nie trać czasu na czytanie artykułów.

Offline rastabaddon

  • Użytkownik

# Maj 30, 2013, 23:55:33
Zalezy jak rozwiazales system wielowatkowosci w swoim kodzie.
Jezeli bys to mi opisal to moze moglbym Ci pomoc.
Pare miesiecy aktualnie siedze nad silnikiem rendrujacym wielowatkowo, rozwiazalem kilka problemow wiec moze cos Ci sie z tego przyda.

Offline Esidar

  • Użytkownik

# Maj 31, 2013, 19:13:23
Nie mam zielonego pojęcia jak to dobrze zsynchronizować. Myślałem o zrobieniu jakiejś kolejki i obsługiwanie pakietów tylko z wątku renderingu... ale nie wiem...
Zrób tak jak sugeruje yarpen. Jest bardzo wiele operacji (nie tylko tych przychodzących z sieci) które wymagają bezpiecznej synchronizacji w jednym miejscu. Już samo przesuwanie obiektu/postaci, z której może czytać kilka wątków, wymaga aby pozycja była zmieniana raz w bezpiecznym miejscu w przeciwnym razie, albo będziesz pobierać pozycję niezainicjowaną poprawnie (np. tylko X jest nowy a Y, Z stare), albo zagrzebiesz się w sekcjach krytycznych i będziesz mieć pełno race conditions (obiekt A modyfikuje B, a obiekt B modyfikuje A).

Najlepiej zrobić kod, który w większości miejsc jest "read-only", a modyfikacje kolejkować, a potem obsługiwać w jednym bezpiecznym miejscu.

Offline cziter15

  • Użytkownik

# Czerwiec 01, 2013, 01:06:20
Dzięki za odpowiedzi. Wcześniej własnie myślałem o tym co podał yarpen. I właśnie tak zrobię.