用C语言fork()实现并发魔法!_c语言并发执行

yumo6662周前 (09-06)技术文章10

多进程编程核心:fork()函数

C语言通过fork()系统调用创建新进程,瞬间复制当前进程(父进程),生成子进程。理解这个"分身术"就掌握了多进程的钥匙。

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

int main() {
    printf(" 父进程启动 PID=%d\n", getpid());
    
    pid_t child_pid = fork();  // 关键分身术!
    
    if (child_pid == 0) {
        // 子进程专属代码区
        printf(" 我是子进程 PID=%d (父进程:%d)\n", 
               getpid(), getppid());
    } else if (child_pid > 0) {
        // 父进程专属代码区
        printf(" 创建了子进程 PID=%d\n", child_pid);
    } else {
        perror("fork失败!");
        return 1;
    }
    
    printf(" 父子进程都会执行这里 PID=%d\n", getpid());
    return 0;
}

运行结果示例:

 父进程启动 PID=1234
 创建了子进程 PID=1235
 我是子进程 PID=1235 (父进程:1234)
 父子进程都会执行这里 PID=1234
 父子进程都会执行这里 PID=1235

关键知识点图解

现象

解释

fork()返回值不同

父进程得到子进程PID,子进程得到0

并发执行

父子进程执行顺序由调度器决定

内存隔离

进程间不共享变量(独立内存空间)


三大实战场景

场景1:并行计算加速(进程池)

#include <sys/wait.h>
#define PROCESS_NUM 4

int main() {
    for(int i=0; i<PROCESS_NUM; i++){
        if(fork() == 0) {
            // 子进程计算任务
            printf("进程%d计算中...\n", getpid());
            sleep(1);  // 模拟计算耗时
            printf("进程%d完成!\n", getpid());
            exit(0);   // 子进程必须退出
        }
    }
    
    // 父进程等待所有子进程
    while(wait(NULL) > 0); 
    printf(" 所有子进程已完成!\n");
    return 0;
}

场景2:进程树构建

int main() {
    pid_t pid1 = fork();  // 第一层分支
    
    if(pid1 == 0) {
        // 子进程1创建孙子进程
        pid_t pid2 = fork();
        if(pid2 == 0) {
            printf("孙进程 PID=%d\n", getpid());
        } else {
            printf("子进程 PID=%d\n", getpid());
            wait(NULL);
        }
    } else {
        printf("父进程 PID=%d\n", getpid());
        wait(NULL);
    }
    return 0;
}

场景3:后台守护进程

int main() {
    pid_t pid = fork();
    
    if (pid > 0) {
        // 父进程退出使子进程成为孤儿
        printf("守护进程启动 PID=%d\n", pid);
        exit(0);  
    }
    
    // 子进程成为守护进程
    setsid();  // 脱离终端控制
    while(1) {
        printf(" 守护进程工作中 PID=%d\n", getpid());
        sleep(5);
    }
    return 0;
}

避坑指南

  1. 僵尸进程预防
  2. 父进程必须用wait()回收子进程资源
  3. 内存写入优化
  4. 使用写时复制(Copy-On-Write)技术减少内存开销
  5. 进程间通信(IPC)
  6. 常用管道/共享内存/信号量

为什么选择多进程?

多进程

多线程

系统级隔离,更安全稳定

共享内存,数据交换更快

利用多核CPU更直接

上下文切换开销小

崩溃互不影响

线程崩溃导致整个进程终止

相关文章

「初识C语言」编译过程_c语言编译过程详解

C语言编译过程认识C编译执行过程,是C学习的开端。我们来简单说C语言从编码编译到执行要经历一下过程:C源代码编译---->形成目标代码,目标代码是在目标机器上运行的代码。连接---->将目...

C语言模块程序设计?源文件和头文件如何划分模块?linux C第32讲

6 .c源文件和.h头文件配合使用假设我们开发一个图书馆管理系统,读者的信息使用reader.c和reader.h文件来管理,那么,读者在登记的时候,需要输入年龄,那么,可以设计如下的函数,接收登记读...

C程序设计之:1-1/2+1/3-... + 1/n 的和

求:1 - 1/2 + 1/3 - .... + 1/n 的和。和这道题不同的是,该题目里面,偶数项是负数,奇数项是正数。#include <iostream> using namespa...

C语言也可以制作视频播放器?只需5分钟即可制作一个自己的播放器

上一节简要的介绍了如何编写C语言程序调用 FFmpeg 库,读取视频文件,并将之逐帧转换为 ppm 图片,最后通过 save_frame() 函数将转换后的 ppm 图片保存到磁盘。本节将在上一节的基...

一起学《C程序设计》第六课——数组、字符串及实战练习

在之前的第三课中学习了基本数据类型,第五课学习了循环结构程序,做练习的时候处理的是一些有规律的数据,比如1~100的正整数,而当我们面对一堆没有规律的数据时该怎么去循环处理呢?把数据组合在一起构成一个...

每天一道c语言编程题,第四题(c语言经典 求素数)

编写一个程序,输入一个整数n,输出n以内的所有素数。#include <stdio.h>int main() { int n, i, j, flag; printf("请输入一...