为什么非阻塞地打开命名管道 return 是一个无效的文件描述符?

Why does opening a named pipe non-blockingly return an invalid file descriptor?

我正在努力巩固我对谁在何时以及为何阻止命名管道打开、写入和读取命名管道的理解。

以下代码暗示使用 O_WRONLY | O_NONBLOCK 打开命名管道是无效的,但我不确定我的代码中是否存在一些我不理解的错误,或者这是否通常是正确的.

// main.c

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

int main( int argc, char* argv[] )
{
  int wfd = open( "/tmp/foo", O_WRONLY | O_NONBLOCK );
  printf( "wfd[%d]\n", wfd );
  if ( wfd >= 0 )
  {
    int res = write( wfd, "0", 1 );
    printf( "write: [%d], errno[%d(%s)]\n", res, errno, strerror( errno ) );
    sleep(3);
    printf( "writer ending!\n" );
  }
  return 0;
}
> ls -l /tmp/foo 
prwxrwxrwx. 1 user user 0 Sep  4 10:35 /tmp/foo
> 
> gcc -g main.c && ./a.out 
wfd[-1]

问题:为什么打开命名管道 O_WRONLY | O_NONBLOCK return 一个无效的文件描述符?

我怀疑这与需要同时打开读端和写端的管道有关,因此我解决这个问题的老套方法(通过非阻塞地打开一端)失败了。但我还没有找到任何具体的文件来支持这个假设或以其他方式解释这个观察结果。

mkfifo(3) - Linux 手册页:

See fifo(7) for nonblocking handling of FIFO special files.

fifo(7) - Linux 手册页:

A process can open a FIFO in nonblocking mode. In this case, opening for read only will succeed even if no-one has opened on the write side yet, opening for write only will fail with ENXIO (no such device or address) unless the other end has already been opened.

John 的回答是正确的,但要解决您的具体问题,"returning an invalid file descriptor" 是错误的。 open returns -1 表示错误。在这种情况下,您可以检查 errno(就像您对 write 所做的那样)以查看错误原因。