C语言 fork() 实战:5种常见父子进程通信模式与代码对比

C语言 fork() 实战:5种父子进程通信模式深度解析与性能对比

在Linux系统编程中,多进程协作是提升程序性能的重要手段。fork()系统调用作为进程创建的基石,其衍生出的父子进程通信问题一直是开发者关注的焦点。本文将深入剖析五种主流IPC(进程间通信)方案,通过可落地的代码示例和量化对比,帮助开发者选择最适合业务场景的通信方式。

1. 进程通信基础与fork()机制精要

当我们在Linux环境下调用fork()时,操作系统会创建一个与父进程几乎完全相同的子进程。这个"几乎"二字背后隐藏着几个关键特性:

  • 写时复制(Copy-On-Write) :现代Linux采用COW机制优化fork性能,父子进程初始共享物理内存页,只有当某方尝试修改数据时才会触发真正的内存复制
  • 执行分流 :通过fork()返回值的差异(父进程获子进程PID,子进程得0)实现代码路径分流
  • 资源继承 :子进程继承父进程的文件描述符表、信号处理方式等环境信息
#include <unistd.h>
#include <stdio.h>

int main() {
    pid_t pid = fork();
    
    if (pid > 0) {
        printf("Parent process (PID:%d) created child (PID:%d)\n", 
               getpid(), pid);
    } else if (pid == 0) {
        printf("Child process (PID:%d) running\n", getpid());
    } else {
        perror("fork failed");
        return 1;
    }
    
    return 0;
}

注意:在多线程程序中调用fork()时,子进程只会复制调用线程的副本,这可能导致死锁等问题。生产环境中建议使用pthread_atfork()注册处理函数

2. 匿名管道:轻量级数据流通道

匿名管道是UNIX系统最古老的IPC形式,适用于父子进程间的单向数据流动。其核心特点包括:

  • 半双工通信 :数据只能单向流动,需要双向通信时应建立两个管道
  • 内核缓冲区 :默认容量为64KB(Linux 5.4+),写满阻塞,读空阻塞
  • 生命周期 :随进程终止自动销毁

典型应用场景 :日志收集、命令管道(如shell中的 | 操作)

#include <unistd.h>
#include <sys/wait.h>

#define BUF_SIZE 256

int main() {
    int pipefd[2];
    char buf[BUF_SIZE];
    
    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

    pid_t pid = fork();
    if (pid > 0) {  // 父进程写
        close(pipefd[0]);  // 关闭读端
        const char* msg = "Message from pare
「LLM那些事」系列第 4 篇《上下文窗口的边界》,文章连接:https://blog.csdn.net/houwenjin/article/details/163999753。 演示什么:在「预测」Sheet 的黄色格子里输入一句话(默认「来泡一杯」),四个「模型」——分别只统计最后 1 / 2 / 3 / 4 个字的 n-gram 查表——同时预测下一个字。同一个输入,看的上下文越长,候选越少、预测越确定: ┌────────────────┬──────────┬───────────────┬──────┐ │ 只看最后几个字 │ 用的前缀 │ 候选下一字数 │ 预测 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 1 个 │ 杯 │ 3(茶/子/水) │ 模糊 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 2 个 │ 一杯 │ 2(茶/水) │ 收窄 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 3 个 │ 泡一杯 │ 1(茶) │ 确定 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 4 个 │ 来泡一杯 │ 1(茶) │ 确定 │ └────────────────┴──────────┴───────────────┴──────┘
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 笔记本的散热风扇管理 ---------------------------------------- 09 November 2006. 对于版本20061109的变更概述如下: 1) ACPI CA核心子系统:在源操作数是一个操作区域的场景下,对负载ASL操作符进行了优化。仅需映射操作区域内存,而不是执行逐字节读取。 (区域必须为SystemMemory类型,见下文。)修正了源操作数为区域字段的负载ASL操作符问题。也允许缓冲区对象作为源操作数。 BZ 480 解决了负载ASL操作符允许源操作数为任意类型操作区域的问题。现被限制为仅SystemMemory类型的区域,符合ACPI规范。 BZ 481 对新表管理器代码进行了额外的清理和优化。AcpiEnable将在所有必需的ACPI表未加载时失败(FADT, FACS, DSDT)。 BZ 477 在acobject.h中添加了#pragma pack(8/4),以确保此头文件中的结构始终编译为对齐。ACPI_OPERAND_OBJECT已被手动优化为对齐,并在字节打包时无法工作。示例代码和数据大小:这些是Microsoft Visual C++ 6.0 32位编译器生成的、操作系统无关的acpica.lib的大小。调试版本的代码包含调试输出跟踪机制,具有更大的代码和数据大小。上一个版本:非调试版本:78.1K代码,17.1K数据,95.2K总计 调试版本:155.4K代码,63.1K数据,218.5K总计 当前版本:非调试版本:77.9K代码,17.0K数据,94.9K总计 调试版本:155.2K代码,63.1K数据,...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值