5

epoll / devpoll / kqueue / poll / select(windows-selectを含む)を使用して、非同期ソケットIOのイベントループを設計しています。

IO操作を実行するための2つのオプションがあります。

非ブロッキングモード、EAGAINでポーリング

  1. ソケットを非ブロッキングモードに設定します。
  2. ソケットへの読み取り/書き込み。
  3. 操作が成功した場合は、完了通知をイベントループに送信します。
  4. EAGAINを取得した場合は、「選択リスト」にソケットを追加し、ソケットをポーリングします。

ポーリングモード:ポーリングしてから実行します

  1. ソケットを追加してリストを選択し、ポーリングします。
  2. 読み取り可能で書き込み可能であるという通知を待つ
  3. 読み書き
  4. sucseedsのイベントループへの完了通知の投稿

私には、通常モードで使用する場合、特にソケットへの書き込みの場合、最初に必要なシステムコールが少なくなるように見えます(バッファーは非常に大きい)。また、「select」実行の数よりもオーバーヘッドを減らすことができるように見えます。特に、epoll / devpoll/kqueueのように拡張性の高いものがない場合に便利です。

質問:

  • 2番目のアプローチの利点はありますか?
  • Linux、FreeBSD、Solaris、MacOSX、Windowsなどの多数のオペレーティングシステムでのソケット/ファイル記述子の非ブロッキング操作に移植性の問題はありますか?

注:既存のevent-loop/socket-api実装の使用を提案しないでください

4

3 に答える 3

3

クロスプラットフォームの問題があるかどうかはわかりません。せいぜい Windows Sockets API を使用する必要がありますが、結果は同じです。

それ以外の場合は、どちらの場合もポーリングしているように見えるため (ブロック待機を回避)、両方のアプローチで問題ありません。自分自身をブロックする立場に置かない限り (たとえば、データがないときに読み取り、バッファーがいっぱいになったときに書き込む)、まったく違いはありません。

おそらく、最初のアプローチの方がコーディング/理解が簡単です。それで、それで行きます。

このトピックに関する興味深いアイデア/アプローチについては、libev のドキュメントとc10k問題をチェックしてみてください。

于 2010-05-06T18:57:21.000 に答える
2

最初のデザインはプロアクター パターン、2 つ目はリアクター パターンです。

リアクター パターンの利点の 1 つは、データが実際に読み取られるまで読み取りバッファーを割り当てる必要がないように API を設計できることです。これにより、I/O を待っている間のメモリ使用量が削減されます。

于 2010-05-10T14:03:37.237 に答える
1

低遅延ソケットアプリでの私の経験から:

書き込みの場合 - 書き込みスレッドからソケットに直接書き込みを試みます (そのためのイベント ループ ミューテックスを取得する必要があります)。書き込みが不完全な場合は、イベント ループ (select/waitformultipleobjects) で書き込み準備をサブスクライブし、ソケットが取得されたときにイベント ループ スレッドから書き込みます。書き込み可能

読み取り用 - すべてのソケットの読み取り準備のために常に「サブスクライブ」するため、ソケットが読み取り可能になると、常にイベントループスレッド内から読み取ります

于 2010-05-10T14:30:41.457 に答える