linux-C/C++主子进程同时占用主进程文件描述符问题

在 Linux 系统中,当一个进程(A)打开文件并获取文件描述符(fd)后,如果通过 system() 启动子进程(B),子进程会继承父进程的所有打开文件描述符。这可能导致多个进程同时写入同一个日志文件,造成日志混乱或数据损坏。

书写辅助函数 set_fd_cloexec 为了解决这个问题。它通过设置 FD_CLOEXEC 标志位,确保在执行 exec 系列函数(如 system() 内部调用的 exec)时,文件描述符会被自动关闭,子进程不会继承该文件描述符。

函数解析

c 复制代码
static void set_fd_cloexec(int fd)
{
    if (fd < 0)  // 检查无效文件描述符
    {
        return;
    }
    int flags = fcntl(fd, F_GETFD);  // 获取当前文件描述符标志
    if (flags == -1)  // 检查获取是否失败
    {
        return;
    }
    fcntl(fd, F_SETFD, flags | FD_CLOEXEC);  // 设置 FD_CLOEXEC 标志
}

关键点说明

  1. FD_CLOEXEC 作用

    设置此标志后,当进程调用 exec 系列函数(如 system() 启动的子进程)时,操作系统会自动关闭该文件描述符,防止子进程继承。

  2. 函数逻辑

    • 先检查 fd 是否有效(fd >= 0
    • 使用 fcntl(fd, F_GETFD) 获取当前标志
    • 通过位或操作 flags | FD_CLOEXEC 添加标志
    • fcntl(fd, F_SETFD, ...) 应用新标志
  3. 使用场景

    在打开文件后立即调用此函数:

    c 复制代码
    int log_fd = open("app.log", O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (log_fd >= 0) {
        set_fd_cloexec(log_fd);  // 确保子进程不继承此 fd
    }

注意事项

  1. 错误处理

    当前函数忽略了 fcntl 的失败情况,实际应用中建议添加错误日志:

    c 复制代码
    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
        perror("fcntl(F_SETFD) failed");
    }
  2. 替代方案

    • 在打开文件时直接设置标志(更推荐):

      c 复制代码
      int fd = open("file.txt", O_RDWR | O_CLOEXEC, 0644);
    • Linux 专有函数:

      c 复制代码
      int fd = open("file.txt", O_RDWR | O_CLOEXEC, 0644);
  3. 继承例外

    若需要特定文件描述符被子进程继承(如标准输入/输出),则不应设置 FD_CLOEXEC

总结

通过正确设置 FD_CLOEXEC 标志,可确保:

  • 父进程(A)正常使用文件描述符
  • 子进程(B)启动时自动关闭该描述符
  • 避免多进程同时写文件导致的冲突
相关推荐
qq_542515411 小时前
Ubuntu 22.04.4 LTS安装ToDesk最新版打不开,无响应?旧版本4.7.2_277版本分享
linux·ubuntu·todesk
火车叼位1 小时前
替代 Tiny Win10 的 Linux 方案:Debian XFCE 精简桌面搭建
linux·运维
小麦嵌入式2 小时前
FPGA入门(四):时序逻辑计数器原理与 LED 闪烁实现
linux·驱动开发·stm32·嵌入式硬件·fpga开发·硬件工程·dsp开发
Byron Loong3 小时前
【c++】为什么有了dll和.h,还需要包含lib
java·开发语言·c++
皮卡蛋炒饭.3 小时前
传输层协议UDP
linux·网络协议·udp
Dlrb12113 小时前
C语言-指针数组与数组指针
c语言·数据结构·算法·指针·数组指针·指针数组·二级指针
坚果派·白晓明3 小时前
【鸿蒙PC三方库移植适配框架解读系列】第一篇:Lycium C/C++ 三方库适配 — 概述与环境配置
c语言·开发语言·c++·harmonyos·开源鸿蒙·三方库·c/c++三方库
syagain_zsx3 小时前
Linux指令初识(实用篇)
linux·运维·服务器
王木风4 小时前
终端里的编程副驾:DeepSeek-TUI-项目深度拆解,实测与原理分析
linux·运维·人工智能·rust·node.js
槑槑紫4 小时前
windows系统装轻量版linux开发
linux·运维·服务器