3

fgets の呼び出しが後でブロックされるかどうかを知るために、C で入力バッファーを覗いたり、同様のトリックを実行したりできるかどうか疑問に思っていました。Java では、BufferedReader.ready() を呼び出すことで、そのようなことを行うことができます。このようにして、次のようなコンソール入力を実装できます。

while (on && in.ready()) { 
  line = in.readLine();
  /* do something with line */
  if (!in.ready())
    Thread.sleep(100);
}

これにより、外部スレッドは on を false に設定することにより、入力ループを適切にシャットダウンできます。移植性のないトリックに頼らずにCで同様の実装を実行したいのですが、シグナルに頼るか、または(バッファリングの処理を要求しても)再実装することにより、UNIXで「タイムアウトしたfgets」を作成できることはすでに知っていますそれは recv/select の上にありますが、Windows でも動作するものを好むでしょう。

ティア

4

2 に答える 2

1

ソケット I/O ルーチンを使用することをお勧めします。できれば、必要なミリ秒をタイムアウトとして poll() を使用することをお勧めします。最終的には、タイムアウト (戻り値 = -1) を入力バッファー内のデータが利用できないものとして解釈できます。
私の意見では、この機能を実現するノンブロッキングの標準 I/O 関数はありません。

于 2010-04-29T10:39:23.237 に答える
0

何について話しているのかわからない: ソケットまたはファイル ハンドル?

ファイルの場合、ブロッキングはありません。関数はすぐに戻ります (I/O 呼び出し自体を除く)。

ソケットの場合 -ioctlsocket関数を使用できます: 以下は、保留中の rcv データがあるかどうかを示します。

ULONG nSize;
ioctlsocket(sock, FIONREAD, &nSize);

以下は、ソケットを非ブロッキング モードに転送します。

ULONG nEnable = 1;
ioctlsocket(sock, FIONBIO, &nEnable);

ノンブロッキング モードの場合 - ソケットの関数はブロックされません。要求を満たすことができない場合、エラーが返されます。エラー コードは次のとおりです。WSAEWOULDBLOCK

さらに、Windows には、はるかに効率的な方法が多数あります。それらは:

  • オーバーラップ I/O の使用。これは自明ではありませんが、優れたパフォーマンスを提供します
  • ソケットを待機可能なイベントに関連付けます。これにより、ソケットが非ブロック モードに移行し、ネットワーク イベントが発生したときに指定されたイベントが通知されます。
  • これをウィンドウ ハンドルに関連付けます。これは、UI 指向のプログラムに便利です。
于 2010-04-29T15:07:53.107 に答える