2

私は2つの異なるバイナリで異なる動作を確認してepollおりselect、デバッグの助けを期待していました。以下では、epoll_waitselect同じ意味で使用されます。

私には、FIFOを介して通信する2つのプロセス(1つはライターと1つはリーダー)があります。リーダーは、epoll_wait書き込みの通知を実行します。また、ライターがいつFIFOを閉じるかを知りたいのepoll_waitですが、これも通知する必要があるようです。次のおもちゃのプログラムは、期待どおりに動作し、私が達成しようとしていることを示しています。

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/stat.h>
#include <unistd.h>

int
main(int argc, char** argv)
{
  const char* filename = "tempfile";
  char buf[1024];
  memset(buf, 0, sizeof(buf));

  struct stat statbuf;
  if (!stat(filename, &statbuf))
    unlink(filename);

  mkfifo(filename, S_IRUSR | S_IWUSR);

  pid_t pid = fork();
  if (!pid) {
    int fd = open(filename, O_WRONLY);
    printf("Opened %d for writing\n", fd);
    sleep(3);
    close(fd);
  } else {
    int fd = open(filename, O_RDONLY);
    printf("Opened %d for reading\n", fd);

    static const int MAX_LENGTH = 1;
    struct epoll_event init;
    struct epoll_event evs[MAX_LENGTH];
    int efd = epoll_create(MAX_LENGTH);

    int i;
    for (i = 0; i < MAX_LENGTH; ++i) {
        init.data.u64 = 0;
        init.data.fd = fd;
        init.events |= EPOLLIN | EPOLLPRI | EPOLLHUP;
        epoll_ctl(efd, EPOLL_CTL_ADD, fd, &init);
    }

    while (1) {
      int nfds = epoll_wait(efd, evs, MAX_LENGTH, -1);
      printf("%d fds ready\n", nfds);
      int nread = read(fd, buf, sizeof(buf));
      if (nread < 0) {
        perror("read");
        exit(1);
      } else if (!nread) {
        printf("Child %d closed the pipe\n", pid);
        break;
      }
      printf("Reading: %s\n", buf);
    }
  }
  return 0;
}

ただし、別のリーダー(コードを投稿する権限はありませんが、まったく同じ呼び出しを行います-おもちゃのプログラムがモデル化されています)でこれを行うと、ライターがFIFOを閉じてもプロセスはウェイクアップしません。おもちゃのリーダーは、で必要なセマンティクスも提供しますselect。使用するように構成された実際のリーダーselectも失敗します。

2つの異なる動作の原因は何でしょうか?提供された仮説について、どのように検証できますか?Linux2.6.38.8を実行しています。

4

1 に答える 1

0

straceは、システムコールが正しく呼び出されたことを確認するための優れたツールです(つまり、パラメーターが正しく渡され、予期しないエラーが返されません)。

それに加えて、lsofを使用して、そのFIFOがまだ開いているプロセスが他にないことを確認することをお勧めします。

于 2012-10-27T13:20:55.990 に答える