首页 > 解决方案 > POSIX FIFO 在阻塞模式下打开时冻结

问题描述

默认情况下,POSIX FIFO 在阻塞模式下打开。我的问题是,当我以阻塞模式打开它时,它只会冻结(阻塞)而没有其他任何反应。

最初我用 RDWR 标志打开了两边,我没有问题,因为 RDWR 使它成为非阻塞,因为“在 Linux 下,打开一个 FIFO 进行读写将在阻塞和非阻塞模式下都成功”(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

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

根据https://www.man7.org/linux/man-pages/man7/fifo.7.html上的 Linux 手册页,“通常,打开 FIFO 块直到另一端也打开。” 太好了,但我无法打开编写器的代码,因为阅读器阻止了所有进一步的进展。这就像墨西哥的对峙。

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

感谢您对此的任何帮助。

标签: clinuxposixnamed-pipesfifo

解决方案


三个选项:

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

推荐阅读