2

UNIX で select() がどのようにパイプを処理すると想定されているかを理解するのに苦労しています。マニュアルページを何度も読みましたが、与えられた定義を完全には理解していません。

マニュアルページを読むと、select() は、指定されたファイル記述子の 1 つが (私の場合は) ブロックせずにパイプから読み取りを行うまで、システムを待機させるという印象を受けました。

これが私のアウトラインコードの一部です[編集済み]:

int size, size2;
fd_set rfds;
struct timeval tv;
char buffer[100];
char buffer2[100];
int retval;

while(1)
{
    FD_ZERO(&rfds);
    FD_SET(fd[0], &rfds);
    FD_SET(fd2[0], &rfds);
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    retval = select(2, &rfds, NULL, NULL, &tv); //2 seconds before timeout

    if(retval == -1)
       perror("Select failed.\n");
    else if(retval)
    {
       size = read(fd[0], buffer, sizeof(buffer));
       if(size > 0)
          printf("Parent received from even: %s\n", buffer);
       size2 = read(fd2[READ], buffer2, sizeof(buffer2));
       if(size2 > 0)
          printf("Parent received from odd: %s\n", buffer2);
    }
    else
       printf("No data written to pipe in 2 last seconds.\n");
}

ここに2本のパイプがあります。2 つの子プロセスがそれぞれのパイプに書き込みを行っており、親は両方を読み込む必要があります。

テストとして、各パイプに小さな文字列を書き込みます。次に、それらを読み込んで、選択によるブロックを防止しようとします。出力される唯一のものは、偶数パイプからの文字列です。まだブロックしているようです。マニュアルページに何かが欠けているように感じて、イライラしています。誰かが私が間違っていることを教えてもらえますか?

4

2 に答える 2

5

戻った後select()、0個以上のファイル記述子が「準備完了」状態になり、ブロックせずに読み取ることができます。ただし、準備ができていないものを読んだ場合でも、ブロックされます。今、あなたはそれらすべてを読んでいます、そしてselect()は1つが準備ができるまで待つだけなので、もう1つは準備ができていない可能性が非常に高いです。

あなたがする必要があるのは、どれが準備ができているか、そしてread()それらからだけであるかを理解することです。の戻り値は、準備ができている数を示し、特定の1つがマクロselect()で準備ができているかどうかを尋ねることができます。ISSET()

于 2012-10-02T01:33:30.143 に答える
1
  1. 使用する必要がありますFD_ZERO()- selectの前を参照してくださいFD_SET
  2. 選択の直前にタイムアウト値を設定します。これらの値は、select
于 2012-10-02T01:22:52.240 に答える