zoukankan      html  css  js  c++  java
  • 僵死进程

    1.僵死进程

    1)一个进程终止了,内核会为它保留一定的信息,包括进程ID、终止状态、使用CPU的时间总量等

    2)为什么内核要保留?因为有时候它的父进程想知道它的退出状态

    3)一个已经终止的进程,但是其父进程由于很忙,尚未对其进行尚后处理(处理保留的信息,彻底释放它的资源),则这个进程在被处理前为僵死进程

    2.孤儿进程

    1)一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程;

    2)孤儿进程将被init进程收养,孤儿进程不会成为僵死进程,因为init进程时刻都wait它的子进程。

    3.wait函数和waitpid函数

    pid_t wait(int* statloc);
    pid_t waitpid(pid_t pid, int* statloc, int options);

    3.1函数作用

    父进程用来尚后处理终止子进程的函数

    3.2参数说明

    1)整型指针statloc如果不是NULL,则终止子进程的终止状态会存放在statloc指向的单元中;

    2)waitpid中pid的含义依据其具体值而变

      pid==-1 等待任何一个子进程,此时waitpid的作用与wait相同
      pid >0   等待进程ID与pid值相同的子进程
      pid==0   等待与调用者进程组ID相同的任意子进程
      pid<-1   等待进程组ID与pid绝对值相等的任意子进程

    3.3区别

    1)如果子进程已经是僵死进程,则wait函数会立刻处理它并返回子进程ID,否则wait函数会使调用者阻塞,直到一个子进程终止;而waitpid函数提供了一个非阻塞的版本

    2)waitpid函数可以等待一个特定的子进程

    4.pthread_join函数

    int pthread_join(pthread_t* tid, void **status)
        //若成功返回0,若出错则返回错误编号

    1)调用pthread_join等待一个给定的线程终止,对比进程,类似于进程中的waitpid(一般在主线程中调用,来等待子线程的终止;一个线程终止了,进程也会为它保留线程ID、终止状态等信息)

    2)如果status非空,则应该为所等待线程的返回值的指针

    5.SIGCHLD信号

    作用:一个进程终止时,它会向父进程发送SIGCHLD信号

    设置成忽略:设置成SIG_IGN的“忽略”和系统默认值的“忽略”是不一样的语意。在SIG_IGN下,子进程的信息会被内核直接丢弃,不会变成僵尸进程;而在系统默认的“忽略”下,内核是会为子进程保留一定的信息的,等待被wait系列函数处理

    6.避免僵死进程的方法

    1)父进程在fork后调用wait/waitpid函数

    2)父进程捕获SIGCHLD信号,并在捕获函数中调用wait/waitpid函数

    3)在进程中设置SIGCHLD信号为忽略,见上

    4)调用两次fork:

      1.父进程fork产生一个子进程,随后就立即执行waitpid()/wait()函数来等待子进程结束

      2.然后儿子进程再fork产生一个孙子进程,接着立即执行exit(0)退出,由于孙子进程失去了它的父进程,那么孙子进程变为孤儿进程被init收养

      3.孙子进程先要执行sleep操作,因为要保证它的父进程先终止,保证它正式被init收养

      4.这样一来孙子进程就可以代替它的父进程来完成需要的事件(父子进程共享正文段),而不会有僵尸进程出现(孤儿进程不会成为僵死进程)

  • 相关阅读:
    测试文件报告
    Bug Variations
    阶段一 问答题2
    阶段一 问答题1
    HeapSort
    Git系列 (01):git clone 速度太慢解决方法
    ES6系列 (03):链判断运算符和Null 判断运算符
    ES6系列 (02):解构赋值
    ES6系列 (01):箭头函数this指向问题
    我忘却了所有,抛却了信仰,舍弃了轮回,只为,那曾在佛前哭泣的玫瑰,早已失去旧日的光泽。
  • 原文地址:https://www.cnblogs.com/Joezzz/p/9818666.html
Copyright © 2011-2022 走看看