3

FIFO とselect()システム コマンドを使用してテストを実行しています。アイデアは次のとおりです。

  1. select()プロセス 1 は、コマンドで FIFO からのメッセージを待機してスリープする必要があります
  2. メッセージが来ない場合、プロセス 1 は 5 秒ごとに起動し、「まだ何もありません」と言う必要があります。
  3. メッセージが着信した場合は、ウェイクアップし、メッセージを出力してから終了する必要があります

コードは次のとおりです:スペースを節約するためにエラーチェックを削除しています:

//process 1's code
int main()
{
  int fd, ret;
  fd_set rfds;
  char buffer[100] = {0}; 
  char * myfifo = "/tmp/myfifo";
  struct timeval tv;

  tv.tv_sec = 5;  // 5 second sleep
  tv.tv_usec = 0;

  mkfifo(myfifo, 0666); //Make the fifo

  fd = open(myfifo, O_RDONLY);
  FD_ZERO(&rfds);    // clear the flags
  FD_SET(fd, &rfds); // set "read" on fd

  while((ret = select(fd+1, &rfds, NULL, NULL, &tv)) <= 0) //should be 1 when we're ready to read
  {
     FD_ZERO(&rfds);     //I believe we should clear/reset these every time?
     FD_SET(fd, &rfds);
     printf("Nothing yet...%d\n",ret);
     fflush(stdout);
  }
  n = read(fd, buffer, 100);
  printf("I got a read of %d bytes\nIt was %s\n",n, buffer);

  unlink(myfifo);

  return 0;
}

プロセス 1 を起動して実行したら、10 秒ほど待ってから、プロセス 2 を開始します。

//Process 2's code
int main()
{
  int fd, n, ret;
  fd_set rfds;
  char buffer[100] = {0};
  char * myfifo = "/tmp/myfifo";
  fd = open(myfifo, O_WRONLY);

  printf("What would you like to send?\n");
  fgets(buffer, 100, stdin);
  write(fd, buffer, strlen(buffer));

  close(fd);
  return 0;
}

私は次のようなものを見ることを期待しています:

Nothing yet...0
Nothing yet...0
I got a read of X bytes
It was <some string>

代わりに、何かを入力してプロセス 2 の Enter キーを押すまで、何も表示されません。プロセス 1 は文字列を正しく返します...しかし、ループがメッセージを出力しないのはなぜですか?

4

2 に答える 2

6

男性選択:

Linux では、select() は、スリープしていない時間を反映するようにタイムアウトを変更します。他のほとんどの実装では、これは行われません。(POSIX.1-2001 では、どちらの動作も許可されています。)

したがって、ループ内でテレビを再初期化する必要があります。しかし、これはあなたの問題の原因ではありません。原因は次のとおりです。

男 mkfifo:

通常、読み取り用に FIFO を開くと、他のプロセスが書き込み用に同じ FIFO を開くまでブロックされます。逆の場合も同様です。

于 2012-09-28T20:00:49.533 に答える
3

Linuxを使用しているので、リーダー側の呼び出しに追加することをお勧めしますO_NONBLOCKopen()詳細については、を参照してくださいman 7 fifo

于 2012-09-29T13:36:56.027 に答える