2012-08-29 3 views
5

Ich schrieb einen kleinen TCP Server mit socket() + POLLINpoll() + recv() + send(), aber ich weiß nicht, wann POLLOUT Umfrage zu verwenden oder writefds wählen auf beschreibbaren Ereignis abzufragen.Wann verwenden Sie das POLLOUT-Ereignis der Poll C-Funktion?

Kann mir jemand ein Beispiel für die tatsächliche Verwendung von POLLOUT geben?

+0

es in der Regel nicht eine sichere Methode;) – Shawn

+0

@Shawn, warum POLLOUT ist nicht sicher? – xiaochen

+0

möglich Duplikat von [Was den Parameter "fd_set * writefds" in der select() -Anweisung für] verwenden soll (http://StackOverflow.com/questions/7076320/what-to-use-the-fd-set-writefds-) parameter-in-the-select-statement-for) –

Antwort

15

Das übliche Muster ist nicht blockierende Filedeskriptoren mit poll() wie folgt zu verwenden:

  • Wenn Sie bereit sind zu poll() bekommen,
    • immer POLLIN gesetzt, weil Sie beim Lesen, was die anderen immer interessiert Ende des Sockets hat dich gesendet.
    • Außer wenn Sie einen großen Rückstand von eingehenden Daten haben und Sie wollen absichtlich das andere Ende warten, bevor Sie mehr senden.
    • Setzen Sie POLLOUT nur, wenn Sie ausstehende Daten an das andere Ende senden müssen.
  • Nach der Rückkehr von poll(), wenn es zeigt an, dass zu lesende Daten vorhanden ist,
    • sie lesen und etwas tun, damit
  • Nach der Rückkehr von poll(), wenn es, dass der Buchse anzeigt, ist beschreibbar,
    • Versuchen Sie, Ihre ausstehenden Daten zu senden.
      • Wenn Sie alle, es zu schreiben geschafft, du gehst nicht POLLOUT nächste Mal durch die Schleife setzen
      • Wenn Sie nur einen Teil davon senden verwaltet (oder nichts davon) halten dann den Rest für später. Sie werden POLLOUT beim nächsten Mal durch die Schleife setzen.
  • Wenn Sie neue Daten zu senden (entweder als Reaktion auf Daten, die Sie lesen oder als Reaktion auf ein externes Ereignis), haben Sie zwei Möglichkeiten:
    • Eifrig versuchen, einige davon zu senden jetzt sofort. Sie können erfolgreich keine, einige oder alle davon senden. Wie im vorherigen Fall, behalte den Teil der Daten, der nicht für das nächste Mal geschrieben wurde und plane, POLLOUT das nächste Mal durch die Schleife zu setzen, nur wenn einige Daten übrig waren.
    • Halten Sie einfach die Daten fest und planen Sie, das nächste Mal POLLOUT durch die Schleife zu setzen. (Diese Wahl ist oft einfacher zu programmieren, weil Sie nur Daten an einer Stelle in Ihrer Schleife schreiben müssen, aber auf der anderen Seite verzögert es das Schreiben der Daten bis zum nächsten Mal durch die Schleife.
    • )
+1

+1 für die detaillierte Ablaufbeschreibung, da es nie gute 'POLLOUT' Beispiele gibt. – laindir

+0

'POLLHUP' soll nicht vom Anrufer eingestellt werden. Es wird vom Kernel gesetzt, wenn es einen Socket erkennt, der geschlossen wurde (Verbindung verloren). –

+0

@AlexisWilke danke für die Korrektur. Ich war nie selbst über "POLLHUP" super sicher und dachte daran, es "nur um sicher zu sein". – Celada

0

Von nginx Quelle, ich fand heraus, dass:

Wenn einige Daten gibt es auszusenden, nginx versucht es mit einem syscall zu schicken (vielleicht writev). Wenn nginx jedoch nicht die gesamten Daten gleichzeitig senden kann, wird POLLOUT auf pollfd gesetzt, wenn Poll-Ereignis verwendet wird, um auf ein beschreibbares Ereignis zu warten. Wenn ein beschreibbares Ereignis erhalten wird, sendet nginx die linken Daten.

Es ist einfach, diesen Fall zu reproduzieren, wenn nginx Reaktion große statische Datei versucht

Verwandte Themen