2009-06-04 7 views
23

Ich habe einen Kommentar über Server-Architektur gelesen.Event Loop vs Multithread-Blockierung IO

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

In diesem Kommentar, sagt die Person 3 Dinge:

  1. die Ereignisschleife, immer wieder wurde für eine hohe Anzahl von geringer Aktivität Verbindungen wirklich glänzt gezeigt.
  2. Im Vergleich dazu wurde ein blockierendes E/A-Modell mit Threads oder Prozessen immer wieder gezeigt, um die Latenz pro Anfrage im Vergleich zu einer Ereignisschleife zu reduzieren.
  3. Auf einem leicht belasteten System ist der Unterschied nicht zu unterscheiden. Unter Last entscheiden sich die meisten Ereignisschleifen für eine Verlangsamung, die meisten blockierenden Modelle entscheiden sich dafür, die Last abzubauen.

Sind alle davon wahr?

Und auch ein weiterer Artikel hier den Titel „Warum Event eine schlechte Idee sind (für Hoch Concurrency-Server)“

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

Antwort

20

Wenn die Anwendung voraussichtlich Millionen von Verbindungen verarbeiten soll, können Sie das Multi-Thread-Paradigma mit ereignisbasierten kombinieren.

  1. Zuerst spawnen Sie als N Threads wo N == Anzahl der Kerne/Prozessoren auf Ihrem Rechner. Jeder Thread wird eine Liste von asynchronen Sockets haben, mit denen er umgehen soll.
  2. Dann, für jede neue Verbindung vom Akzeptor, "Load-Balance" der neue Sockel an den Thread mit der wenigsten Steckdose.
  3. Verwenden Sie in jedem Thread das ereignisbasierte Modell für alle Sockets, sodass jeder Thread mehrere Sockets gleichzeitig verarbeiten kann.

Mit diesem Ansatz

  1. Sie nie eine Million Threads erzeugen. Sie haben nur so viele, wie Ihr System verarbeiten kann.
  2. Sie verwenden ereignisbasiertes Multicore statt eines einzelnen Kerns.
+0

Können Sie bitte, wenn möglich, einige konkrete Beispiele nennen? Vielen Dank! – Jeff

+1

Ja richtig. Zeig mir deine Implementierung. –

+1

Es ist einfach mit QThreadPool und QRunnable zu implementieren. Überprüfen Sie http://doc.qt.nokia.com/4.7-snapshot/qthreadpool.html – sivabudh

0

nicht sicher, was Sie durch „niedrige Aktivität“ bedeuten, aber ich glaube, die Haupt Faktor wäre, wie viel Sie tatsächlich tun müssen, um jede Anfrage zu bearbeiten. Unter der Annahme einer single-threaded Ereignisschleife würden keine anderen Clients ihre Anforderungen behandeln, während Sie die aktuelle Anfrage bearbeitet haben. Wenn Sie eine Menge Dinge erledigen müssen, um jede Anfrage zu bearbeiten ("Lose" bedeutet etwas, das viel CPU und/oder Zeit benötigt), und vorausgesetzt, Ihre Maschine ist tatsächlich in der Lage effizient zu multitasking Ressource, wie eine einzelne CPU-Maschine oder ähnliches), würden Sie eine bessere Leistung durch Multitasking erhalten. Multitasking könnte ein Multithreading-Blockierungsmodell sein, aber es könnte auch eine Singletasking-Ereignisschleife sein, die eingehende Anfragen sammelt und sie an eine Multithread-Worker-Factory weiterleitet, die diese wiederum (durch Multitasking) behandelt und Ihnen so schnell wie möglich eine Antwort sendet.

Ich glaube nicht, dass langsame Verbindungen mit den Clients so wichtig sind, da ich glaube, dass das Betriebssystem das effizient außerhalb Ihrer App handhaben würde (vorausgesetzt, Sie blockieren die Ereignisschleife für mehrere Roundtrips mit dem Client zunächst nicht initiiert die Anfrage), aber ich habe das selbst nicht getestet.

+0

Diese Antwort muss aufgeräumt werden. –