Linux下回收子进程wait函数和waitpid函数的基本使用

2019-07-14 11:16发布

1. 孤儿进程:父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程变为init进程 。 2. 僵尸进程:子进程终止了,父进程尚未回收子进程,子进程残留资源(PCB)存放于内核中,子进程变成僵尸(Zombie)进程。  问:那为什么子进程要把PCB残留在内核里呢?  答:因为子进程终止后,它会把终止信号等退出状态(不管正常终止还是异常终止都对应一个信号)保存在内核的PCB里面,只有这个子进程的父亲节调用wait或者waitpid获取这些退出状态,然后才会彻底清除掉这个子进程。如果父进程不调用wait或者waitpid,那么这个子进程就会成为僵尸进程。 问:什么方法可以清除掉一个僵尸进程。(附:kill命令清除不了僵尸进程的,因为kill命令只是用来终止进程的,而僵尸进程已经是终止的了)  答:kill确实是直接清除不掉僵尸进程,但是我们可以kill掉僵尸进程的父进程,这样僵尸进程的父进程就变为init进程,init进程自然会调用wait或者waitpid清除这个僵尸进程。  3. wait函数 pid_t wait(int *status); //status传出参数,存放子进程的退出状态信息 附:父进程一旦调用该函数,就会阻塞等待,直到子进程退出 返回值:成功返回子进程id,失败返回-1(无子进程) 。 status传出参数保存着子进程的退出状态,下面对其说明如下: if (WIFEXITED(status)) { //IFEXITED非0,进程正常退出                         printf("exited, status=%d ", WEXITSTATUS(status));                     } else if (WIFSIGNALED(status)) { //IFSIGNALED非0,进程被某个信号异常终止                         printf("killed by signal %d ", WTERMSIG(status));                     } else if (WIFSTOPPED(status)) { //IFSTOPPED非0,进程收到某个信号而暂停                        printf("stopped by signal %d ", WSTOPSIG(status));                     } else if (WIFCONTINUED(status)) { //IFCONTINUED非0,进程从暂停状态变为继续运行状态                         printf("continued ");                     }  4. waitpid函数  pid_t waitpid(pid_t pid, int *status, int options);  功能:和wait一样,但是这个函数清除指定的pid,可以不阻塞父进程 返回值:成功返回清除掉的进程pid,失败返回-1 (无子进程) 。当options指定为WNOHANG时,返回0表示子进程正在运行。 下面对pid的不同取值情况的说明: >0  表示回收指定ID的子进程 -1   表示回收任意子进程(相当于wait) 0    表示回收和当前调用waitpid一个组的所有子进程 <-1 表示回收指定进程组内的任意子进程,比如-6610表示回收进程组id为6610的任意子进程 附:一次wait或waitpid调用只能清理掉一个子进程,清理多个子进程应该使用循环调用多次 。 参考:https://www.cnblogs.com/yongfengnice/p/6796356.html     python父进程起一个线程回收结束子进程 def wait_son(): while True: time.sleep(3) try: pid,stat = os.waitpid(-1, os.WNOHANG) if pid: if os.WEXITSTATUS(stat) == 0: print "ok,child process over" else: print "not ok" except Exception as e: print e threading.Thread(target=wait_son, args=()).start() 有回收代码块的情况:可以看到僵尸进行有2变为0 没有回收代码块的情况:可以看到僵尸一直为2 #coding=utf-8 import time,os import threading import multiprocessing def mth(i): print "test{}".format(i) for i in xrange(0,100): t = multiprocessing.Process(target=mth,args=(i,)) #t.setDaemon(False) #t = threading.Thread(target=mth,args=(i,)) t.daemon=False t.start() def wait_son(): while True: time.sleep(3) try: pid,stat = os.waitpid(-1, os.WNOHANG) if pid: if os.WEXITSTATUS(stat) == 0: print "ok,child process over" else: print "not ok" except Exception as e: print e #threading.Thread(target=wait_son, args=()).start() time.sleep(1000)