2012-08-29 2 views
5

は私がsocket() + POLLINpoll() + recv() + send()で小さなTCPサーバを書いたが、書き込み可能なイベントをポーリングするwritefdsPOLLOUTポーリングを使用するか選択するようにするとき、私は知りません。ポールC関数のPOLLOUTイベントをいつ使用するのですか?

誰でも私に実際の使用例を教えてくださいPOLLOUT

+0

通常は安全な方法ではありません。 ) – Shawn

+0

@Shawn、なぜPOLLOUTは安全でないのですか? – xiaochen

+0

の[select()ステートメントの "fd_set * writefds"パラメータを使用する理由(http://stackoverflow.com/questions/7076320/what-to-use-the-fd-set-writefds-詳細なフロー記述については、 –

答えて

15

いつものパターンは、このようなpoll()と非ブロックファイル記述子を使用することです:あなたはいつも何他を読んで興味を持っているので、poll()への準備をするとき

    • は必ずPOLLINを設定しましたソケットの端があなたを送ります。
      • 受信データのバックログが大きく、さらに送信する前に相手先を待機させたい場合を除きます。
    • POLLOUTは、相手側に送信する未処理データがある場合にのみ設定します。 poll()から戻ると
  • 、それはデータが読み取り可能であることを示している場合、
    • それはそのソケットを示している場合、それを読み、poll()から戻ると、それ
  • で何かを行います書き込み可能です、
    • あなたの未処理データを送信してみてください。あなたはそれのすべてを書くことに成功した場合
      • は、あなたはそれだけの一部(またはそれのどれも)を送信するために管理している場合、ループ
      • を通じてPOLLOUT次の時間を設定するために、残りを維持するつもりはありません後で。ループの次回にはPOLLOUTを設定します。熱心にそれのいくつかを送信しよう
        • あなたが(どちらかあなたが読んだり、何らかの外部イベントに応答したデータに応答して)送信するために、新たなデータを持っている
    • 、次の2つの選択肢があり直ちに。あなたは正常に送信することができます、いくつか、またはすべての。前のケースと同様に、次回のために書き込まれなかったデータの部分を保存しておき、データが残っている場合にのみ、ループを使用して次にPOLLOUTを設定します。
    • データを保持して、次回にループを設定するときはPOLLOUTに設定してください。 (この選択は、ループ内のある場所にデータを書き込むだけで済むため、プログラムを作成する方が簡単ですが、ループの次回まではデータを書き込むのが遅れます。nginxのソースから)
+1

+1というパラメータを使用してください。これは決して良いPOLLOUTの例がないためです。 – laindir

+0

POLLHUPは発信者によって設定されません。これは、閉じられたソケットが検出された場合にカーネルによって設定されます(接続が失われた)。 –

+0

@AlexisWilkeは訂正してくれてありがとう。私は決して「ポップホップ」について自分自身を非常に確信しておらず、「確かに」と設定すると考えました。 – Celada

0

、私がことがわかった:送信するためにいくつかのデータがある場合は、nginxのは、システムコール(多分writev)でそれを送信しようと

。しかし、nginxが一度に合計データを送信できない場合、ポーリングイベントを使用している場合はpollfdにPOLLOUTを設定して、書き込み可能なイベントを待機します。書き込み可能なイベントを取得すると、nginxは左のデータを送信します。

nginxが大きな静的ファイルに応答しようとすると、このケースを再現するのは簡単です

関連する問題