基于FIFO管道的双向进程通信聊天程序运行异常排查
基于FIFO的双用户聊天程序修复方案
问题根因分析
- 异常1(发送继续后卡住):原代码将最多5条消息的发送逻辑封装在单次写FIFO的循环内,用户选择继续发送时会连续写入消息,没有切换到读流程接收对方回复,双方收发时序完全错位导致死锁。
- 异常2(选结束后无bye直接退出):user2代码存在变量未定义错误,声明了
YN变量但实际使用未定义的sendAgain接收用户输入,运行时触发内存访问异常直接崩溃;同时原代码缺少收到bye后的终止逻辑,退出流程不完整。 - FIFO使用逻辑错误:FIFO为半双工通信管道,同一时间仅支持单向传输,必须每完成一次单方向传输就关闭对应端、切换读写状态,否则会出现读写阻塞。
修复后的代码
user1 代码(先发后收逻辑)
//Chat 1 // This side writes first, then reads #include <stdio.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main() { int fd, count=0,sendAgain=0; char * myfifo = "/tmp/myfifo"; // 先删除已存在的FIFO避免历史文件冲突 unlink(myfifo); mkfifo(myfifo, 0666); char Arr1[80], Arr2[80]; while (count < 5) { count++; // 发送当前消息 fd = open(myfifo, O_WRONLY); printf("\nYour message: "); fgets(Arr1, 80, stdin); write(fd, Arr1, strlen(Arr1)+1); close(fd); // 询问是否继续聊天 printf("Do you want to continue?[1 or 2]\n1-Yes\n2-No\nAnswer: "); scanf("%d",&sendAgain); getchar(); // 选择结束则发送bye后主动退出 if (sendAgain == 2) { fd = open(myfifo, O_WRONLY); write(fd, "bye", strlen("bye")+1); close(fd); printf("You have ended the chat.\n"); exit(0); } // 接收对方回复 fd = open(myfifo, O_RDONLY); read(fd, Arr2, sizeof(Arr2)); // 收到对方bye消息直接退出 if(strcmp(Arr2, "bye") == 0) { printf("User2 has ended the chat: %s\n", Arr2); close(fd); exit(0); } printf("User2: %s\n", Arr2); close(fd); } // 发满5条自动发送bye后退出 fd = open(myfifo, O_WRONLY); write(fd, "bye", strlen("bye")+1); close(fd); printf("You have sent up to 5 messages, chat ended.\n"); return 0; }
user2 代码(先收后发逻辑)
//Chat 2 // This side reads first, then writes #include <stdio.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main() { int fd1, count=0,sendAgain=0; char * myfifo = "/tmp/myfifo"; // 等待user1完成FIFO创建,避免重复创建冲突 sleep(1); char str1[80], str2[80]; while (count < 5) { count++; // 接收对方消息 fd1 = open(myfifo,O_RDONLY); read(fd1, str1, sizeof(str1)); if(strcmp(str1, "bye") == 0) { printf("User1 has ended the chat: %s\n", str1); close(fd1); exit(0); } printf("User1: %s\n", str1); close(fd1); // 发送当前消息 fd1 = open(myfifo, O_WRONLY); printf("\nYour message: "); fgets(str2, 80, stdin); write(fd1, str2, strlen(str2)+1); close(fd1); // 询问是否继续聊天 printf("Do you want to continue?[enter 1 or 2]\n1-Yes\n2-No\nAnswer: "); scanf("%d",&sendAgain); getchar(); // 选择结束则发送bye后主动退出 if (sendAgain == 2) { fd1 = open(myfifo, O_WRONLY); write(fd1, "bye", strlen("bye")+1); close(fd1); printf("You have ended the chat.\n"); exit(0); } } // 发满5条自动发送bye后退出 fd1 = open(myfifo, O_WRONLY); write(fd1, "bye", strlen("bye")+1); close(fd1); printf("You have sent up to 5 messages, chat ended.\n"); return 0; }
使用说明
- 运行前先执行命令删除残留FIFO文件:
rm -f /tmp/myfifo - 先启动user1程序,再启动user2程序,双方按照发-收交替逻辑通信
- 任意一方选择结束聊天、或发送满5条消息,都会自动发送bye通知对方,双方同步终止程序
内容的提问来源于stack exchange,提问作者Mera
相关产品推荐
相关产品推荐

