C++命名管道(FIFO)读写功能异常,请求代码问题排查
命名管道(FIFO)进程间通信代码问题排查
需求回顾
需要实现两个基于命名管道的C程序,满足:
- 接收用户输入的目录路径,搜索该目录下的FIFO类型文件;未找到则提示重新输入,找到后一个程序以读模式打开,另一个以写模式打开。
- 写模式程序从终端输入消息并通过管道发送给读模式程序,读模式程序读取管道消息并输出到终端;双方在发送/接收
END后结束进程(注:原需求中“读模式程序发送消息”的描述存在角色矛盾,读模式仅能读取管道,推测为需求表述误差)。
当前代码存在的核心问题
读进程代码问题
- mkfifo错误处理逻辑错误:
mkfifo返回-1时,若错误原因是EEXIST(FIFO已存在),属于正常情况,无需退出。当前代码只要mkfifo失败就直接退出,导致FIFO已存在时程序无法正常运行。 - 文件描述符混用:
mkfifo的返回值是0(成功)或-1(失败),并非文件描述符。但代码中错误地将fp作为文件描述符传入read和close,正确的文件描述符是open返回的numop。 - 操作逻辑完全颠倒:读进程先尝试从FIFO读取数据,再从终端读取输入,最后打印终端输入的内容,完全不符合“读取管道消息并输出”的需求。
- 错误的文件关闭操作:代码中
close(fp)关闭的是mkfifo的返回值,而非open得到的读端文件描述符numop,会导致资源泄漏。 - 未实现目录搜索FIFO的逻辑:直接硬编码使用当前目录下的
myfifo,没有接收用户输入的目录路径,也没有搜索该目录下的FIFO文件。 - 未实现
END结束逻辑:没有判断读取的消息是否为END,无法触发进程退出。
写进程代码问题
- 缺少字符串处理头文件:使用了
strlen函数,但未包含<string.h>,会导致编译警告或错误。 - 未实现目录搜索FIFO的逻辑:同样直接硬编码
myfifo,未处理用户输入的目录路径及FIFO搜索。 - 未实现
END结束逻辑:没有判断输入的消息是否为END,发送后直接退出,无法满足循环通信直到END的需求。 - fgets参数不合理:
fgets(sentence,250,stdin)中,数组长度为256,可改为255(留一个位置给字符串结束符),避免潜在的边界问题。
修正方向建议
- 修正FIFO创建与打开逻辑:读进程中,
mkfifo失败时检查errno,若为EEXIST则继续执行打开操作;确保使用open返回的正确文件描述符进行读写和关闭。 - 明确程序角色:写模式程序以
O_WRONLY打开FIFO,负责从终端输入消息并写入管道;读模式程序以O_RDONLY打开FIFO,负责读取管道内容并输出到终端。 - 实现目录搜索FIFO逻辑:
- 接收用户输入的目录路径。
- 遍历目录下的文件,通过
stat函数判断文件类型是否为S_IFIFO(FIFO类型)。 - 未找到则提示用户重新输入,找到后使用该FIFO路径进行打开操作。
- 添加
END结束逻辑:- 写程序循环读取终端输入,若输入为
END则发送后退出。 - 读程序循环读取FIFO内容,若读取到
END则输出后退出。
- 写程序循环读取终端输入,若输入为
- 补充必要头文件:写进程中添加
<string.h>头文件。
内容的提问来源于stack exchange,提问作者yoonamain
相关产品推荐
相关产品推荐

