Ich erstelle einen Multithreadserver mit epoll (flankengetriggert) und nicht blockierenden Sockets. Momentan erstelle ich eine Ereignisschleife auf dem Hauptthread und warte auf Benachrichtigungen und es funktioniert korrekt. Ich muss zwischen zwei Ansätzen wählen, um Multithread zu machen:
Wenn ich die erste Methode verwende, besteht die Möglichkeit, dass mehrere Threads mit demselben Ereignis benachrichtigt werden? Wie kann ich mit dieser Situation umgehen?
Was könnte der beste Ansatz sein? Danke.
Ich denke, dass Option 1 populärer ist, da der Hauptzweck von nicht blockierenden IO darin besteht, den Overhead von create & amp; Zerstöre Fäden.
nehmen Sie den populären Webserver nginx als ein Beispiel, es erstellt mehrere Prozesse (keine Threads), um ankommende Ereignisse auf einem Handle zu behandeln und die Ereignisse im Unterprozess zu verarbeiten. Sie alle teilen sich die gleiche Abhörbuchse. es ist ziemlich ähnlich zu Option 1.
Ich schreibe auch einen Server mit epoll
, und ich habe das gleiche Modell wie Sie angehängt.
Es ist möglich, Option 1 zu verwenden, aber es kann zu einem "donnernden Herdeneffekt" kommen. Sie können die Quelle von nginx lesen, um die Lösung zu finden. Wie für Option 2, ich denke, dass es besser ist, Thread-Pool zu verwenden, anstatt jedes Mal einen neuen Thread zu erstellen.
Und Sie können auch das folgende Modell:
Haupt-Thread / Prozess: accept
eingehende Verbindung mit blockierendem IO und sende das fd an die anderen Threads mit BlockingList oder an die anderen Prozesse mit PIPE
.
Sub-Threads / Prozess: Erstellen Sie jeweils eine Instanz von epoll
und fügen Sie das eingehende fd zu epoll
hinzu und verarbeiten Sie sie dann mit nicht blockierenden IO.
epoll ist threadsicher, eine gute Lösung ist, dass Ihr Hauptprozess in accept (2) bleibt, sobald Sie den Dateideskriptor in der epoll fd für den Zielthread registrieren lassen, bedeutet das, dass Sie eine epoll-Warteschlange dafür haben Jeder Thread, nachdem Sie den Thread erstellt haben, teilen Sie den Epoll-Dateideskriptor als Parameter im Aufruf pthread_create (3). Wenn also eine neue Verbindung eintrifft, führen Sie epoll_ctl (... EPOLL_CTL_ADD ..) mit dem Befehl epoll fd für das Ziel aus thread und der neue Socket nach accept (2) erstellt, sinnvoll?
Eine Ereignisschleife für jeden Thread ist die flexibelste mit hoher Leistung Sie sollten ein epoll fd für jede Ereignisschleife erstellen, es gibt keine Bedenken hinsichtlich des Thread-sicheren Problems von epoll.
Tags und Links c multithreading sockets linux epoll