僵尸进程

僵尸进程

匿名 (未验证) 提交于 2019-12-03 00:29:01
而僵尸进程就是指:一个进程执行了exit系统调用退出,而其父进程并没有为它收尸(调用wait或waitpid来获得它的结束状态)的进程。 任何一个子进程(init除外)在exit后并非马上就消失,而是留下一个称外僵尸进程的数据结构,等待父进程处理。这是每个子进程都必需经历的阶段。另外子进程退出的时候会向其父进程发送一个SIGCHLD信号。 (在一个进程终止或者停止时,将SIGCHLD信号发送给其父进程。按系统默认将忽略此信号。如果父进程希望被告知其子系统的这种状态,则应捕捉此信号。信号的捕捉函数中通常调用wait函数以取得进程ID和其终止状态。) js.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <signal.h> int main( int arg, char *args[]) { pid_t pid=fork(); //注册信号,屏蔽SIGCHLD信号,子进程退出,将不会给父进程发送信号,因此也不会出现僵尸进程 // signal(SIGCHLD,SIG_IGN); if (pid==- 1 ) { printf ( "fork() failed! error

僵尸进程和孤儿进程

匿名 (未验证) 提交于 2019-12-02 23:51:01
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。 等待父进程正常结束后会调用wait/waitpid去回收僵尸进程 但如果父进程是一个死循环,永远不会结束,那么该僵尸进程就会一直存在,僵尸进程过多,就是有害的 解决方法一:杀死父进程 解决方法二:对开启的子进程应该记得使用join,join会回收僵尸进程 创建完子进程后,主进程所在的这个脚本就退出了,当父进程先于子进程结束时,子进程会被init收养,成为孤儿进程,而非僵尸进程 import os import sys import time pid = os.getpid() ppid = os.getppid() print 'im father', 'pid', pid, 'ppid', ppid pid = os.fork() #执行pid=os.fork()则会生成一个子进程 #返回值pid有两种值: # 如果返回的pid值为0,表示在子进程当中 # 如果返回的pid值>0,表示在父进程当中 if pid > 0:

杀死僵尸进程

匿名 (未验证) 提交于 2019-12-02 23:40:02
使用 kill -9 PID 无法杀死一个进程. 这个进程可能是一个僵尸进程(Zombie Process). 查看僵尸进程: ps -ef | grep defunc 每行有两个进程ID,分别是子进程的进程ID和父进程的进程ID ps -ef | grep defunct | more 杀死僵尸进程的父进程: kill -9 PPID

重读APUE(12)-SIGCHLD与僵尸进程

落花浮王杯 提交于 2019-12-02 22:07:38
SIGCHLD信号是当子进程终止时向父进程发送的信号;它的语义如下: 如果进程明确的将该信号设置为SIG_IGN,则调用进程不会产生僵尸进程;这种情况下,wait是等不到给子进程收尸的,所以wait阻塞到所有子进程终止后,返回-1,并且将errno设置为ECHILD; 如果进程没有明确的设置捕获该信号,那么将会是默认处理SIG_DFL(忽略),这种情况下,如果不使用wait函数,会产生僵尸进程; 如果进程明确的设置捕获该信号,则内核立即检查是否子进程准备好被等待,如果是,则调用SIGCHLD处理程序,当然也需要使用wait函数,否则会产生僵尸进程; 补充:使用sigaction可以设置SA_NOCLDWAIT标志,也可以避免产生僵尸进程; 可见,除了调用wait函数族来避免僵尸进程之外,还可以通过显示的设置SIGCHLD信号为忽略,或者通过sigaction设置SA_NOCLDWAIT标志来避免产生僵尸进程; 来源: https://www.cnblogs.com/wanpengcoder/p/11764246.html

Linux 僵尸进程如何处理

匿名 (未验证) 提交于 2019-12-02 21:53:52
Linux 允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait() 这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。 为了遵循这些设计原则,不允许 Linux 内核在进程一终止后就丢弃包含在进程描述符字段中的数据。只有父进程发出了与被终止的进程相关的 wait() 类系统调用之后,才允许这样做。这就是引入僵死状态的原因:尽管从技术上来说进程已死,但必须保存它的描述符,直到父进程得到通知。 如果一个进程已经终止,但是它的父进程尚未调用 wait() 或 waitpid() 对它进行清理,这时的进程状态称为僵死状态,处于僵死状态的进程称为僵尸进程(zombie process)。任何进程在刚终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了。 僵尸进程是如何产生的 为了观察到僵尸进程,我们自己写一个不正常的程序,父进程 fork 出子进程,子进程终止,而父进程既不终止也不调用 wait 清理子进程: 把上面的代码保存到文件 zomprocdemo.c 文件中,并执行下面的命令编译: 然后运行编译出来的 zomprocdemo 程序: 此时子进程已经退出,但是父进程没有退出也没有通过 wait() 调用处理子进程。我们使用 ps

C/C++网络编程8——多进程服务器端之销毁僵尸进程

天大地大妈咪最大 提交于 2019-12-01 20:38:17
  上一节提到,当子进程执行结束,父进程还在执行,在父进程结束之前子进程会成为僵尸进程,那么怎么销毁僵尸进程呢?父进程主动接收子进程的返回值。 销毁僵尸进程的方法:   1:使用wait函数   2:使用waitpid函数   3:利用信号 来源: https://www.cnblogs.com/418ks/p/11717203.html

进程

廉价感情. 提交于 2019-11-30 02:54:09
1、孤儿进程: 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。 2、僵尸进程: 僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源 我们都知道进程的工作原理。我们启动一个程序,开始我们的任务,然后等任务结束了,我们就停止这个进程。 进程停止后, 该进程就会从进程表中移除。在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,

进程创建&僵尸进程&孤儿进程

南楼画角 提交于 2019-11-29 19:21:01
一、创建并开启子进程的两种方式 1.1方式一 #单个进程 from multiprocessing import Process import time def Text(): print('我是一个子进程') print('我的进程开始了') time.sleep(2) print('我的进程结束了') if __name__ == '__main__': #windows下必须要写这一句,不然会报错 p = Process(target = Text) #实例化产生一个对象 p.start() # 告诉操作系统我要开子进程,告诉完了这行代码就算执行完了,接着往下走,具体操作系统什么时候开子,开多长时间跟你没关系 time.sleep(5) print('我是主进程,我要结束了') #多个进程 from multiprocessing import Process import time def Text(x): print(f'我是子进程{x}') print(f'{x}的进程开始了') time.sleep(2) print(f'{x}的进程结束了') if __name__ == '__main__': #windows下必须要写这一句,不然会报错 p1 = Process(target = Text,args=('yjy',)) #实例化产生一个对象 子进程1 p2 =

僵尸进程与孤儿进程

北慕城南 提交于 2019-11-29 09:55:56
僵尸进程与孤儿进程 僵尸进程指的是父进程的子进程结束时父进程没有被wait()情况下,子进程会变成僵尸进程 父进程等着所有的子进程结束才会结束 孤儿进程是指一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作 情况1 无害 父进程等着子进程都死,回僵尸进程 情况2 无害 父进程死了,子进程还活着,都要被init接管并且回收 情况3 父进程一直不死,造成了大量僵尸进程,占用了大量的pid号 pid号是有限的 最直接的解决方案就是杀死父进程 来源: https://www.cnblogs.com/aden668/p/11511909.html

并发编程之多进程

旧时模样 提交于 2019-11-28 22:27:56
并发编程之:多进程 一 multiprocessing模块介绍 ​ python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。 ​ multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。   multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。 ​ 需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。 二 Process类的介绍 ​ 创建进程的类 : Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动) 强调: 1. 需要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 ​ 参数介绍: 1 group参数未使用,值始终为None 2 3 target表示调用对象,即子进程要执行的任务 4 5 args表示调用对象的位置参数元组