2

次のように、関数fgetsを使用して、stdinからループを読み取るプログラムを作成しています。

while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
  //Some code  
}

コードを非ブロッキングにしたい、つまり、ユーザーからの入力がないときにプログラムが「fgets」行を保持したくない。
どうすればいいですか?

4

5 に答える 5

4

fgets()はブロッキング関数であり、データが利用可能になるまで待機することを意図しています。

非同期 I/O を実行する場合は、、、または を使用select()できpoll()ますepoll()。利用可能なデータがある場合は、ファイル記述子から読み取りを実行します。

これらの関数は、以下によって取得された FILE* ハンドルのファイル記述子を使用します。

int fd = fileno(f);

Unix または Linux を使用している場合、1 つの解決策として、ファイルが使用するファイル記述子をノンブロッキングとしてマークすることができます。例:

#include <fcntl.h>  
FILE *handle = popen("tail -f /als/als_test.txt", "r"); 
int fd = fileno(handle);  
flags = fcntl(fd, F_GETFL, 0); 
flags |= O_NONBLOCK; 
fcntl(fd, F_SETFL, flags); 

fgets現在は非ブロックである必要があり、null を返し、エラー コードを設定します。

于 2011-05-19T08:23:02.620 に答える
2

適切な POSIX 環境があれば、select()orを使用して、 ...を呼び出す前に の記述子のpoll()入力をチェックできます。stdinfgets()read()

以下の Jan のコメント (ありがとう!) は、このアプローチを使用できない理由を説明していますfgets()... 要約すると、FILEオブジェクトには追加のバッファリング層があり、データは既に待機している可能性がありますがselect()、ファイル記述子には何も見つかりません.. . プログラムがタイムリーに応答できなくなり、さらに送信する前に他のシステムが既に送信されたデータへの応答を待機している場合、ハングする可能性がありstdinます。

于 2011-05-19T08:22:20.227 に答える
1

基本的に2つのオプションがあります。

  1. そのループを別のスレッドで実行します。
  2. OSが非ブロッキングIO用のAPIをサポートしているかどうかを確認してください。
于 2011-05-19T08:20:40.707 に答える
0

これは少しやり過ぎのように聞こえるかもしれませんが、これが私の頭に浮かぶものです。

2 つの異なるスレッドを使用します。1 つはこのループを使用し、ブロッキングを待機しています (これは非ブロッキングで実行できるとは思いません)。そして、何かが読み取られたら、それをパイプに押し込みます。

その間、他のスレッドは必要なことは何でも実行し、パイプ内のデータを時々チェックします (明らかに、これを非同期にしたい、または少なくとも私はこの方法で取得します。そうであれば、これは別のスレッドを意味します)

ただし、2 つのスレッドを十分に同期させる必要があります。マルチスレッドと IO 操作について OS を確認する必要があります。

于 2011-05-19T08:21:24.307 に答える
0

Linux では、 ctrl-dを押すことで入力の終了を指定できます。もちろん、別のスレッドを使用してこれを行うこともできます。

于 2011-05-19T08:35:23.227 に答える