• Linux fork和vfork函数用法


    forkvfork是用于创建新进程的函数,在Linux的C语言编程中非常常见。

    fork函数

    fork函数是用于创建一个新的进程,新进程是调用进程的副本。新进程将包含调用进程的地址空间、文件描述符、栈和数据。在fork之后,父进程和子进程将并发执行。

    • fork后会有两个并发程序执行
    • 子进程复制了父进程的数据段,包括全局变量

    fork函数原型:

    pid_t fork(void);
    
    • 1

    fork函数返回值为:

    • 如果是在父进程中,返回新创建的子进程的进程ID;
    • 如果是在子进程中,返回0;
    • 若出现错误,返回-1。
    #include 
    #include 
    #include 
    /**
     * fork后会有两个并发程序执行
     * 子进程复制了父进程的数据段,包括全局变量
    */
    int main() {
        pid_t val;
        printf("PID before fork(): %d\n",getpid());
        val = fork();
        // *********************************************************************
        if(val == 0) {
            printf("I am the child process, PID is %d\n", getpid());
        } else if(val > 0) {
            printf("I am parent process, PID is %d\n", getpid());
        } else {
            printf("Error");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    image-20231121145831531

    fork语句后开始父进程和子进程。

    image-20231121150110720

    vfork函数

    vfork函数是Linux和Unix系统中用于创建新进程的另一个函数,与fork函数类似,但行为有所不同。vfork创建的新进程与调用进程共享地址空间,这样可以减少内存的使用。然而,需要注意的是,在子进程调用execexit之前,父进程会被阻塞。

    • vfork创建的子进程与父进程共享地址空间
    • 调用vfork创建子进程后,父进程会被挂起,直到子进程结束
    #include 
    #include 
    #include 
    /**
     * vfork创建的子进程与父进程共享地址空间
     * 调用vfork创建子进程后,父进程被挂起,直到子进程结束。
    */
    int A = 0;
    int B = 0;
    int main()
    {
        pid_t val;
        val = vfork();
        if(val == 0) {
            ++A, ++B;
            printf("A: %d , B: %d\n", A, B);
        } else {
            ++A, ++B;
            printf("A: %d , B: %d\n", A, B);
    
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    image-20231121150436009

    如果将vfork换为fork

    #include 
    #include 
    #include 
    int A = 0;
    int B = 0;
    int main()
    {
        pid_t val;
        val = fork();
        if(val == 0) {
            ++A, ++B;
            printf("A: %d , B: %d\n", A, B);
        } else {
            ++A, ++B;
            printf("A: %d , B: %d\n", A, B);
    
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    image-20231121150526469

    可以发现:vfork创建的子进程与父进程共享地址空间。

  • 相关阅读:
    分布式存储 vs. 全闪集中式存储:金融数据仓库场景下的性能对比
    挑战100天 AI In LeetCode Day03(热题+面试经典150题)
    springboot配置注入增强(四)使用框架实现自定义数据源和自定义属性解析
    Supervisor - 用户进程监控利器
    二叉树,平衡二叉树,B树,B+树,红黑树
    LeetCode - 743 网络延迟时间
    【随机过程】布朗运动
    Games104现代游戏引擎笔记 网络游戏进阶架构
    全网最全音视频媒体流
    skywalking9.2.0源码修改
  • 原文地址:https://blog.csdn.net/qq_63432403/article/details/134532575