You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用open()函数操作FIFO时出现无限阻塞问题的技术问询

FIFO open()调用无限阻塞的原因与解决方案

先看一下你提供的代码:

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

int main(){
    int fd;
    size_t size;
    char name[]="aaa.fifо"; // 注意:这里最后一个字符是俄文的"о",不是英文的"o",建议修正
    umask(0) ;
    if (mknod(name, S_IFIFO | 0666, 0) < 0){
        printf("Can't create FIFO\n");
        _exit(-1);
    }
    if ((fd = open(name, O_WRONLY)) < 0){
        printf("Can't open FIFO for writing\n");
        _exit(-1);
    }
    char message[60];
    while(true){
        message[0] = 0;
        std::cin.clear();
        std::cin >> message;
        if(!strcmp(message,"exit")) {
            printf("Exit to programm\n");
            break;
        }
        size = write(fd, message, 60);
        if (size < strlen(message)) {
            printf("Can't write all string to FIFO\n");
            _exit(-1);
        }
    }
    close(fd);
    return 0;
}

问题根源:FIFO的默认打开行为

你遇到的open()无限阻塞是FIFO(命名管道)的设计特性:当你以O_WRONLY模式打开FIFO时,内核会一直阻塞这个调用,直到有另一个进程以O_RDONLY模式打开同一个FIFO。这是为了保证数据不会被写入到没有读者的管道中(避免数据丢失)。

你的代码只实现了写端,但没有对应的读端进程,所以open()会一直等待读端连接,自然无法继续执行后续逻辑。

解决方案

这里有两种常用的解决方式,根据你的实际需求选择:

1. 先启动一个读进程(推荐的标准用法)

FIFO是用于进程间通信的,所以正常使用需要读写两端都存在。你可以:

  • 写一个简单的读端程序,比如:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(){
    int fd;
    char name[]="aaa.fifo"; // 注意修正为英文的"o"
    char buffer[60];
    if ((fd = open(name, O_RDONLY)) < 0){
        printf("Can't open FIFO for reading\n");
        _exit(-1);
    }
    while(read(fd, buffer, 60) > 0){
        printf("Received: %s\n", buffer);
    }
    close(fd);
    return 0;
}
  • 或者直接用命令行工具临时作为读端:在终端执行 cat < aaa.fifo(注意要和你的FIFO名字一致,记得修正名字里的俄文字符)。

启动读进程后,再运行你的写进程,open()就会立即返回,程序可以正常执行。

2. 打开时添加O_NONBLOCK标志(非阻塞模式)

如果你不需要等待读端,或者想自己处理无读端的情况,可以在open()时添加O_NONBLOCK标志,让调用立即返回:

if ((fd = open(name, O_WRONLY | O_NONBLOCK)) < 0){
    printf("Can't open FIFO for writing\n");
    _exit(-1);
}

但要注意:此时如果没有读端,write()会失败(返回-1,errno设置为EPIPE),所以你需要在write()后增加错误处理逻辑,避免程序直接退出。

额外注意事项

你的代码里FIFO名字是"aaa.fifо",最后一个字符是俄文的"о"(不是英文的"o"),这会导致你用普通命令行工具(比如ls)查看时,名字可能显示异常,甚至读进程找不到这个FIFO。建议把它改成英文的"aaa.fifo",避免不必要的问题。

内容的提问来源于stack exchange,提问作者Naxal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 11:57:37