C 是否可以将事件文件描述符与中断驱动输入结合使用?

C 是否可以将事件文件描述符与中断驱动输入结合使用?,c,linux,io,system-calls,C,Linux,Io,System Calls,以下是故意忽略错误检查和信号安全的最小可能示例: #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/eventfd.h> #include <stdio.h> #include

以下是故意忽略错误检查和信号安全的最小可能示例:

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/eventfd.h>
#include <stdio.h>
#include <sys/wait.h>

void reader(int a)
{
  printf("hello!\n");
  wait(NULL);
  exit(EXIT_SUCCESS);
}

int main()
{
  signal(SIGIO, reader);
  int efd = eventfd(0, EFD_NONBLOCK);
  fcntl(efd, F_SETOWN, getpid());
  int flags;
  flags= fcntl(efd, F_GETFL);
  fcntl(efd, F_SETFL, flags | O_ASYNC);

  pid_t p = fork();
  if (p)
  {
    for(;;)
      pause();
  }
  else 
  {
    uint64_t buff = 1;
    if (write(efd, &buff, sizeof(buff)) == -1)
      printf("write error\n");
    exit(EXIT_SUCCESS);
  }
}
这段代码应该在子项写入事件文件描述符后在父项中生成SIGIO,但它不会。我甚至尝试从eventfd系统调用中删除EFD_NONBLOCK,我得到了相同的行为。这里有几个问题

这是处理中断驱动I/O的正确方法吗


中断驱动I/O可以与事件文件描述符结合使用吗?如何结合使用?

调用eventfd返回的文件描述符与通过调用写入更改内容时生成信号无关

如果希望父级在每次调用文件描述符时唤醒,请使用8字节的值。写入,然后让父用户选择其中的输入变量包含从调用toeventfd返回的文件描述符

eventfd的linux手册页包含如何使用eventfd函数的示例

select的linux手册页包含如何使用select函数的示例。

eventfd文件描述符不支持O_异步标志

这似乎描述了O_异步功能的所有当前实现者:

此功能仅适用于终端、伪终端、套接字以及Linux 2.6管道和FIFO

通常,如果具体文件不支持O_ASYNC标志,它将被静默忽略。您可以检查以下F_GETFL是否成功设置了该标志:

// Try to set the flag
int flags;
flags= fcntl(efd, F_GETFL);
fcntl(efd, F_SETFL, flags | O_ASYNC);
// Check whether the flag is set
int new_flags = fcntl(efd, F_GETFL);
if(!(new_flags & O_ASYNC)) {
    // Failed to set the flag.
}
有人建议fcntl返回错误,如果要设置特定文件不支持的O_异步标志。是其中之一。但根据内核函数的当前实现,它们已被拒绝:

if (((arg ^ filp->f_flags) & FASYNC) && filp->f_op->fasync)

FASYNC是O_ASYNC的同义词,->FASYNC回调(如果存在)实现了对具体文件标志的更改。

我不想使用select、poll、epoll等.API。这个问题清楚地说明了中断驱动的I/O,它导致信号被传送。我知道如何将它与select一起使用,但它不适合我的需要。问题清楚地表明,您希望使用eventfd返回的文件描述符来生成信号。这不会发生。但在使用FIFO和管道时可能会收到信号,所以我想知道是否有人知道解决方法。谢谢!我在寻找某种报告,为什么它不能工作,但什么也找不到。当系统调用以静默方式失败时,会非常混乱。我接受你的答案。F_SETFL mode fcntl会自动忽略一些标志。当O_ASYNC标志被设置为不合适的文件时,可能会选择相同的决定作为O_ASYNC标志。我已经更新了我的答案,添加了更多细节和检测方式,无论标志是否已成功设置。