2009-06-04 16 views
23

Czytałem komentarz na temat architektury serwera.Pętla zdarzeń vs blokowanie wielowątkowe IO

http://news.ycombinator.com/item?id=520077

W tym komentarzu, osoba mówi 3 rzeczy:

  1. Pętla zdarzeń, czas i ponownie okazał się naprawdę zabłysnąć na dużą liczbę połączeń o niskiej aktywności.
  2. Dla porównania, blokujący model IO z wątkami lub procesami był wielokrotnie pokazywany, aby zmniejszyć opóźnienie na żądanie w porównaniu do pętli zdarzeń.
  3. W lekko obciążonym systemie różnica jest nie do odróżnienia. Pod obciążeniem większość pętli zdarzeń zwalnia, a większość modeli blokujących decyduje o zrzucaniu obciążenia.

Czy któreś z nich są prawdziwe?

A także inny artykuł tutaj zatytułowany „Dlaczego wydarzenia są złym pomysłem (dla serwerów wysoka współbieżności)”

http://www.usenix.org/events/hotos03/tech/vonbehren.html

Odpowiedz

20

Zwykle, jeśli aplikacja ma obsługiwać miliony połączeń, można łączyć wielowątkowy paradygmat z oparta na zdarzeniach.

  1. Najpierw odrodzimy jako N wątków, gdzie N == liczba rdzeni/procesorów na komputerze. Każdy wątek będzie miał listę asynchronicznych gniazd, z którymi ma obsługiwać.
  2. Następnie, dla każdego nowego połączenia z akceptora, "zrównoważyć obciążenie" nowe gniazdo do wątku z najmniejszą liczbą gniazd.
  3. W każdym wątku używaj modelu opartego na zdarzeniach dla wszystkich gniazd, aby każdy wątek mógł obsługiwać wiele gniazd jednocześnie.

Dzięki takiemu podejściu,

  1. Nigdy nie tarło milion wątków. Po prostu masz tyle, ile może obsłużyć twój system.
  2. Wykorzystujesz zdarzenie oparte na wielordzeniu, a nie na pojedynczym rdzeniu.
+0

Czy możesz podać jakieś konkretne przykłady, jeśli to możliwe? Dzięki! – Jeff

+1

Tak, dobrze. Pokaż mi swoją implementację. –

+1

Jest łatwy do wdrożenia za pomocą QThreadPool i QRunnable. Sprawdź http://doc.qt.nokia.com/4.7-snapshot/qthreadpool.html – sivabudh

0

Nie wiem, co masz na myśli przez „niskiej aktywności”, ale uważam, że głównym czynnikiem jest to, ile faktycznie trzeba zrobić, aby obsłużyć każde żądanie. Zakładając jednotomową pętlę zdarzeń, żaden inny klient nie będzie mógł obsłużyć swoich żądań podczas obsługi bieżącego żądania. Jeśli musisz zrobić wiele rzeczy, aby obsłużyć każde żądanie ("dużo" oznacza coś, co wymaga znacznego czasu procesora i/lub czasu), i zakładając, że twoja maszyna jest w stanie efektywnie wykonywać wiele zadań (że poświęcenie czasu nie oznacza czekania na udostępnienie zasoby, jak pojedynczy procesor lub coś podobnego), można uzyskać lepszą wydajność dzięki wielozadaniowości. Wielozadaniowość może być wielowątkowym modelem blokującym, ale może być również pętlą zdarzeń o pojedynczym zadaniu, zbierającą przychodzące żądania, przenoszącą je do wielowątkowej fabryki pracowniczej, która obsługiwałaby te po kolei (poprzez wielozadaniowość) i wysyłając odpowiedź JAK NAJSZYBCIEJ.

Nie sądzę, że powolne połączenia z klientami mają tak duże znaczenie, ponieważ uważam, że system operacyjny poradziłby sobie z tym skutecznie poza aplikacją (zakładając, że nie blokuje się pętli zdarzeń w przypadku wielokrotnych wizyt w obie strony z klientem, który początkowo zainicjował wniosek), ale sam tego nie przetestowałem.

+0

Ta odpowiedź musi zostać uporządkowana. –