进程控制

进程创建:

  fork函数:

    作用:从已经存在进程中创建一个新进程,新进程为子进程,而原进程为父进程。

    执行:

      • 分配新的内存块和内核数据结构给子进程
      • 将父进程部分数据结构内容拷贝至子进程中
      • 添加子进程到系统进程列表中
      • fork返回,开始调度器调度

    返回值:子进程返回0  父进程返回的是子进程的pid

  vfork函数:

    创建出来的父子进程用同一块地址空间(子进程先运行,在子进程调用exit退出或程序替换之后,父进程才退出)

    (在自子进程没有运行其他程序或退出前,父进程阻塞在vfork处不会返回)

    这里的子进程不能用return 退出,否则会释放内存,导致父进程调用混乱。(每一个操作系统是不一样的:Centos 下父进程会进入死循环的状态)

    意义:快速创建子进程,并且子进程是专门来运行其他进程的,共用地址空间可以减少子进程数据拷贝父进程的消耗,因此速度快

    但是这种函数在fork()实现了写时拷贝技术的时候就淘汰了

  写时拷贝技术:

    执行一个程序的时候,先将程序拷贝进物理内存(不一定连续),在创建一个父进程,与虚拟地址及页表,通过页表的映射将虚拟地址空间与物理内存连接,在创建一个子进程,以同样的方式创建了虚拟地址及页表,只不过在子进程的页表中,映射的不在是原来的程序,会为子进程重新创建一块内存拷贝原来的程序,就这样保证了数据独有。(这种拷贝只会在当你使用子进程的变量的时候才会拷贝)

  fork调用失败原因:

    1.系统中有太多的进程

    2.实际用户的进程数超过了限制

进程终止:

  方式:(库函数封装系统调用函数)

    1.main函数中return 

    2.exit()——库函数(在退出前会刷新缓冲区,做退出收尾工作)

      在退出的时候会逐步释放所有资源

      在进程的任意位置调用exit都会退出进程

    3._exit()——系统调用函数(不h会刷新缓冲区,直接退出,释放资源)

      

    异常退出时:ctrl+c;信号终止

  返回值:(返回值只用了一个字节来保存)

    命令:  echo $? (查看系统调用错误返回值)

  错误原因:

    每一个系统调用执行完毕后都会重置进程中的errno这么一个全局变量,这个全局变量中存储的就是当次调用的系统接口错误编号,当系统调用接口出错,用户就可以通过这个errno获取系统调用的错误原因

进程等待:等待子进程的状态改变

  作用:避免僵尸进程的产生

  僵尸进程产生原因:父进程不知道子进程什么时候退出,这时候子进程退处,操作系统的通知由于父进程并没有关注到,导致子进程不能被完全释放,而进入僵尸状态

  必要性:

    1.子进程退出,如果父进程不管,则会造成内存泄露

    2.进程一旦变为僵尸进程则很难被杀死,kill -9 也不能杀

    3.我们必须要获得子进程完成的如何,是否正常完成任务

    4.通过等待的方式,父进程回收子进程资源,获取子进程的退出信息

  调用:

    wait()——阻塞函数

      功能:等待任意一个子进程退出(只要有一个子进程退出就会返回)

      阻塞:为了完成功能发起的调用,如果当前不具备完成条件,则一直等待,直到完成后返回

      非阻塞:为了完成某个功能,如果当前不具备完成条件,则立刻报错返回

    pid_t waitpid(int pid, int* statu, int opt)——opt选项参数:WNOHANG(如果没有子进程退出,则立刻把报错返回,如果有,则里回收资源)

      功能:可以等待任意一个子进程退出或指定一个子进程退出

        opt为0则是非阻塞

        waitpid可以通过opt将操作设为非阻塞

      返回值:

        -1:等待任意子进程退出

        >0:等待子进程退出 

        0:没有子进程退出或出错

      获取返回值statu:   

        statu中保存的元素:
          int 的4个字节中高16位没有使用,使用低16位:
            其中高8位:
            1.子进程的退出返回值:返回值储存在高 8 位中后低 8 位又分为 2 位:
            2.(1b)core dump标志:程序退出时是否保存运行信息
            3.(7b)异常退出信号值:正常退出值为0;

        获取返回值(只有当程序正常退出去返回值才有意义):
          异常信号值为0则正常退出;
          (statu >> 8)& 0xff

          判断程序是否正常退出:
            1.statu & 0x7f
              0 为正常退出
              非0 为异常退出
            2.WIFEXITED(statu)——宏
              正常退出返回ture
              WEXITSTATUS(status) 在程序退出时,获取子进程的退出码

 

posted on 2019-06-17 09:34  The_Ocean  阅读(197)  评论(0编辑  收藏  举报

导航