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

基于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;
}

使用说明

  1. 运行前先执行命令删除残留FIFO文件:rm -f /tmp/myfifo
  2. 先启动user1程序,再启动user2程序,双方按照发-收交替逻辑通信
  3. 任意一方选择结束聊天、或发送满5条消息,都会自动发送bye通知对方,双方同步终止程序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:06:01