• 进程控制fork vfork,父子进程,vfork保证子进程先运行


    主要函数:

    fork 用于创建一个新进程

    exit 用于终止进程

    exec 用于执行一个程序

    wait 将父进程挂起,等待子进程结束

    getpid 获取当前进程的进程ID

    nice 改变进程的优先级

    ---------------------------------

    孤儿进程:

    如果一个子进程的父进程先于子进程结束,子进程就成为一个孤儿进程,他由init进程收养,成为init进程的子进程。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    
    int main() 
    {
    
        pid_t pid;
        pid = fork();
        
        switch( pid )
        {
            case 0:
            {
                while(1)
                {
                    printf("child pid:%d, parent pid:%d
    ", getpid(), getppid());
                    sleep(1);
                }
            }
            case -1:
            {
                printf("create child process error
    ");
                exit(-1);
            }
            default:
            {
                sleep(3);
                printf("I am parent,pid:%d
    ", getpid());
                exit(0);
            }
    
        }
    
        return 0;
        
    }

    child pid:9670, parent pid:9669
    child pid:9670, parent pid:9669
    child pid:9670, parent pid:9669
    I am parent,pid:9669
    root@wilson-software:~/Project/xa# child pid:9670, parent pid:1
    child pid:9670, parent pid:1
    child pid:9670, parent pid:1
    child pid:9670, parent pid:1
    child pid:9670, parent pid:1
    child pid:9670, parent pid:1

    从输出结果来看,父进程停止后,子进程变成了孤儿进程,此时子进程的父进程ID 是 1,

    (init进程的进程ID值始终是1)由init进程收养。

    ------------------------------------------------------------------------------

    vfork函数创建一个子进程时,操作系统并不将父进程的地址空间完全复制到子进程,用vfork函数创建的子进程共享父进程的地址空间,

    也就是说子进程完全运行在父进程的地址空间上。子进程对该地址空间中任何数据的修改同样为父进程所见。

    使用fork创建一个子进程时,哪个进程先执行取决于系统的调度。

    而vfork创建一个子进程时,vfork保证子进程先运行,子进程调用exec或者exit之前父进程处于阻塞等待状态。

    如果在调用exec或者exit之前子进程要依赖父进程的某个行为,就会导致死锁。

    如果创建子进程的目的只是为了调用exec执行某个程序,那么fork过程中子进程对父进程地址空间的复制将会是一个多余的过程。

    vfork不会拷贝父进程的地址空间,这大大减小了系统开销。

    使用vfork时要谨慎,最好不要允许子进程修改与父进程共享的全局变量和局部变量

     -------------------------------------------------------------------------------------------------------------------------------------------------

    父子进程结束的先后顺序不同会产生不同的结果:

    父进程先退出,子进程后退出,则系统会让init进程接管子进程。

    当子进程先退出,而父进程又没有调用wait函数等待子进程结束,子进程进入僵死状态,并且会一直保持下去除非系统重启。子进程处于僵死状态时,内核只保存该进程的

    一些必要信息以备父进程所需。此时子进程始终占用着资源,同时也减少了系统可以创建的最大进程数。如果子进程先于父进程结束,并且父进程调用了wait或waitpid函数,

    则父进程会等待子进程。

  • 相关阅读:
    Dapr牵手.NET学习笔记:状态管理之dockercompose发布
    Dapr牵手.NET学习笔记:跨物理机负载均衡服务调用
    Dapr牵手.NET学习笔记:状态管理进阶(一)
    ORACLE EBS 点滴积累之AP 应付
    SpringMVC框架搭建(idea2021.3.2) 操作数据库
    Linux判断服务进程存在,存在则重启,不存在则启动
    C++ thread lambda expression contains multiple function and pass argument
    C++ thread pass multiple functions and arguments via lambda expression
    C++ multi thread
    C++ bubble sort
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/6387422.html
Copyright © 2020-2023  润新知