• 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创建的子进程与父进程共享地址空间。

  • 相关阅读:
    Vue 3.4.5深度解析:从基础到高级,掌握Composition API与全局API精髓
    大模型prompt实例:知识库信息质量校验模块
    计算机图形学入门28:相机、透镜和光场
    ArcGIS矢量化并进行拓扑检查
    十四、流式编程(2)
    Spring高级
    06_openstack之创建云主机和常见错误
    【离散数学】谓词逻辑
    Samb共享用户的设置和修改Linux用户的id号,修改Linux组的id号,加入组,删除组成员等
    关于mybatisplus报错:Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplat的问题
  • 原文地址:https://blog.csdn.net/qq_63432403/article/details/134532575