POSIX FIFO 在阻塞模式下打开时冻结

POSIX FIFO freezes when opened in blocking mode

默认情况下,POSIX FIFO 以阻塞模式打开。我的问题是,当我以阻塞模式打开它时,它只是冻结(阻塞)并且没有其他任何事情发生。

最初我用 RDWR 标志打开两侧,我没有遇到任何问题,因为 RDWR 使它成为非阻塞,因为 "Under Linux, opening a FIFO for read and write will succeed both in blocking and nonblocking mode" (https://linux.die.net/man/7/fifo)。但是在非阻塞模式下我有时会丢失记录,所以我需要以阻塞模式打开它。

我是这样调用 mkfifo 的:

int64_t fifo_setup(char * fifo_name)
{
    if (mkfifo(fifo_name, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH) == -1) {
        perror("mkfifo");
        exit(EXIT_FAILURE); }

   return 0; }

我原来的打开电话:

int64_t fifo_open(char * fifo_name, int64_t read_write) {

    int c;

    if (read_write == 1) { 
        c = open(fifo_name, O_RDWR);}
    if (read_write == 2) { 
        c = open(fifo_name, O_RDWR);}

    perror("open");

    return (c);
}

然后我改成了:

int64_t fifo_open(char * fifo_name, int64_t read_write) {

    int c;

    if (read_write == 1) { 
        c = open(fifo_name, O_WRONLY);}
    if (read_write == 2) { 
        c = open(fifo_name, O_RDONLY);}

    perror("open");

    return (c);
}

我的程序达到编写器线程的开放调用(这是对 C 的 NASM 调用):

Open_FIFO_Write:
lea rdi,[fifo_name]
mov rsi,1
call fifo_open wrt ..plt
mov [fifo_write_fd],rax

但是随后 Putty 终端冻结(阻塞)并且没有其他任何事情发生。我从来没有到达打开阅读面的街区。具体来说,它会在上面的 fifo_open 代码中到达 perror("open") 之前阻塞:

根据 https://www.man7.org/linux/man-pages/man7/fifo.7.html 的 Linux 手册页,"Normally, opening the FIFO blocks until the other end is opened also." 很好,但我无法找到打开编写器的代码,因为 reader 块所有进一步的进展。这就像墨西哥的对峙。

当然一定有办法,但我的研究还没有找到。

感谢您对此提供的任何帮助。

三个选项:

  1. FIFO 本身不会在非阻塞模式下丢弃消息。如果您的代码正在丢弃消息,请修复您的代码以停止这样做,然后只使用非阻塞模式。
  2. 以非阻塞模式打开FIFO,然后在两端打开后,使用fcntl将其更改为阻塞模式。
  3. 使用单独的线程或进程打开 FIFO 的每一半。