12

stdin が閉じられたときに実行を停止するには、純粋な C で書かれたプログラムが必要です。

プログラムのメイン サイクルで行われる無期限の作業があり、ブロッキング チェック (のようなgetc()) を使用する方法はありません (標準入力にデータが到着することは想定されていません - 未知の時間だけ開かれたままになります)。

inetd、xinetd、またはそれらの類似物でホストされているネットワークデーモンの実現に説明されている機能を使用する予定です-接続が開いたままの状態で標準出力にデータを出力し、閉じたときに作業を正しく終了する必要があります。接続が終了しても停止しないため、ホスティングサービスによってプログラムが強制終了されました。

fctntl()標準入力記述子にO_NONBLOCKフラグを適用すると、read()ノンブロッキング モードで関数を使用できるようになるのでしょうか? select()どうにか使えばいいのでは?

PS データは想定されていませんが、stdin に到着する可能性があります。ノンブロッキング読み出しの方法は、質問に対する答えになるでしょう。

4

5 に答える 5

8

select()はまさにあなたが望むことを行います: ファイル記述子 (ファイル、ソケットなど) に対する操作 (この場合は読み取り) がブロックされないことを通知します。

#include <stdio.h>
#include <sys/select.h>

int is_ready(int fd) {
    fd_set fdset;
    struct timeval timeout;
    int ret;
    FD_ZERO(&fdset);
    FD_SET(fd, &fdset);
    timeout.tv_sec = 0;
    timeout.tv_usec = 1;
    //int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
     struct timeval *timeout);
    return select(fd+1, &fdset, NULL, NULL, &timeout) == 1 ? 1 : 0;
}

たとえば、ファイル記述子を空にするために、使用前にファイル記述子をチェックできるようになりました。

void empty_fd(int fd) {
    char buffer[1024];
    while (is_ready(fd)) {
        read(fd, buffer, sizeof(buffer));
    }
}

あなたの場合、fileno(stdin)を使用して stdin のファイル記述子を取得します。

if (is_ready(fileno(stdin))) {
    /* read stuff from stdin will not block */
}
于 2009-10-20T13:12:01.833 に答える
2

標準入力記述子に O_NONBLOCK フラグを適用した fctntl() を使用すると、ノンブロッキング モードで read() 関数を使用できるようになるのでしょうか?

O_NONBLOCK を指定して stdin を実行すると、select よりも利点があります。Select は、いくつかのデータがあることを示していますが、その量はありません。キューの量に関係なく、利用可能なすべてのデータを取得したいが、ブロックしたくない場合があります。キャラクターごとに select を実行するのは大変な作業のようです... O_NONBLOCK は私にはうまくいきませんでした。これは内部フラグであり、ほとんどの tty ドライバーでは公開されていません。

ioctl(..., FIONBIO) をチェックしてください。仕事が捗りそうです。

于 2012-07-05T12:30:07.833 に答える
1

標準入力に O_NONBLOCK を設定できるかどうかはわかりませんが、select()確実poll()に仕事を終わらせることができます。

于 2009-10-20T12:43:12.493 に答える
0

何が問題なのfeof(stdin)ですか?

于 2009-10-20T12:34:41.837 に答える
0

はい、使用できますselect(タイムアウトなし)。ただし、ファイル記述子を非ブロックに設定する必要はありません-selectファイル記述子が読み取り可能であることが示されている場合、そのread上で a は間違いなくブロックされません。

そのため、ファイル記述子 0 を でときどきポーリングしselect、読み取り可能な場合はそれを行いreadます。0 を返す場合read、それは閉じられたことを意味します。

于 2009-10-20T12:48:04.700 に答える