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

如何在程序终止时正确关闭无限循环中使用的FIFO(命名管道)

实现方案

核心思路

通过注册信号处理函数捕获终止信号(CTRL+C触发的是SIGINT,主进程主动终止一般会给子进程发SIGTERM),在信号处理函数中修改全局的退出标志位,业务循环检测到标志位变化后跳出循环,执行文件描述符关闭、资源清理等逻辑后再退出进程。
注意:信号处理函数中仅做标志位修改即可,不要调用非异步信号安全的复杂函数,所有清理逻辑统一放在循环外执行

代码修改示例

写入端(writer)修改后代码

#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

// 用volatile sig_atomic_t保证信号操作的原子性,避免编译器优化导致标志位不生效
volatile sig_atomic_t exit_flag = 0;

void sig_handler(int sig) {
    exit_flag = 1;
}

int main() {
    int myfifo_fd;
    char buffer[81];
    // 注册信号捕获逻辑,覆盖CTRL+C、主进程终止两种场景
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);

    // 原有打开管道逻辑
    myfifo_fd = open(myfifo, O_WRONLY);
    if (myfifo_fd < 0) {
        perror("open fifo failed");
        return 1;
    }

    while(!exit_flag) { // 原有while(1)改为判断退出标志
        if (fgets(buffer, 80, stdin) == NULL) { // 输入异常时也触发退出
            break;
        }
        write(myfifo_fd, buffer, 81);
    }

    // 退出前统一清理资源
    close(myfifo_fd);
    // 如果是当前进程创建的命名管道,可在此处加unlink(myfifo)删除管道文件
    return 0;
}

读取端(reader)修改后代码

#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

volatile sig_atomic_t exit_flag = 0;

void sig_handler(int sig) {
    exit_flag = 1;
}

int main() {
    int myfifo_fd;
    char buffer[81];
    char last_command[81] = "0";
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);

    myfifo_fd = open(myfifo, O_RDONLY | O_NONBLOCK);
    if (myfifo_fd < 0) {
        perror("open fifo failed");
        return 1;
    }

    while(!exit_flag) {
        int read_len = read(myfifo_fd, buffer, 81);
        if (read_len > 0) {
            strncpy(last_command, buffer, sizeof(last_command)-1);
        }
        do_something(last_command);
        usleep(10000); // 非阻塞读场景加短休眠,避免空转占满CPU
    }

    close(myfifo_fd);
    return 0;
}

注意事项

  • 如果需要处理主进程异常崩溃的场景,可以额外给子进程注册SIGHUP信号的处理逻辑,父进程退出后子进程会收到SIGHUP,同样触发退出清理流程
  • 如果业务逻辑中存在可中断的阻塞调用,不需要额外修改,信号触发后阻塞调用会直接返回错误,循环会正常检测到退出标志

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:24:03