Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1744416
  • 博文数量: 391
  • 博客积分: 8464
  • 博客等级: 中将
  • 技术积分: 4589
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-13 15:12
个人简介

狮子的雄心,骆驼的耐力,孩子的执著!

文章分类

全部博文(391)

文章存档

2023年(4)

2018年(9)

2017年(13)

2016年(18)

2014年(7)

2013年(29)

2012年(61)

2011年(49)

2010年(84)

2009年(95)

2008年(22)

分类: LINUX

2013-07-22 16:29:40

kill掉父进程,其下的子进程也跟着消亡:
例如:
[root@qht2 ~]# ps -ef | grep httpd
root 3799 1 0 10:41 pts/0 00:00:00 /usr/sbin/nss_pcache off /etc/httpd/alias
root 3803 1 3 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3807 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3808 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3809 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3810 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3811 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3812 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3813 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
apache 3814 3803 0 10:41 ? 00:00:00 /usr/sbin/httpd
root 3816 3749 0 10:42 pts/0 00:00:00 grep httpd
[root@qht2 ~]# kill 3803
[root@qht2 ~]# ps -ef | grep httpd
root 3820 3749 0 10:42 pts/0 00:00:00 grep httpd
显然kill掉父进程,子进程也消亡了!

写了两个脚本a.sh 和b.sh, 在a.sh中调用b.sh,运行后显然有两个进程,而且a.sh为b.sh的父进程,然后我再另外一个terminal中kill 掉a.sh进程,但b.sh过寄给init进程,而不会终止!
我的例子如下:
[root@qht2 ~]# cat a.sh
#!/bin/sh
echo "A Begin"
./b.sh
echo "A End"
[root@qht2 ~]# cat b.sh
#!/bin/sh
echo "B Begin"

sleep 180
mkdir abcdef
echo "B End"
[root@qht2 ~]# ./a.sh
A Begin
B Begin
在这里等待(因为b.sh中有sleep 180)


打开另一个terminal,查看进程
[root@qht2 ~]# ps -ef | grep sh
。。。。。。
root 3984 3749 0 11:05 pts/0 00:00:00 /bin/sh ./a.sh
root 3985 3984 0 11:05 pts/0 00:00:00 /bin/sh ./b.sh ##显然b.sh是a.sh的子进程
root 3990 3838 0 11:05 pts/1 00:00:00 grep sh
[root@qht2 ~]# kill 3984
[root@qht2 ~]# ps -ef | grep sh
。。。。。。
root 3985 1 0 11:05 pts/0 00:00:00 /bin/sh ./b.sh
root 3992 3838 2 11:06 pts/1 00:00:00 grep sh

第一ternimal中的显示如下:
[root@qht2 ~]# ./a.sh
A Begin
B Begin
Terminated
但b.sh还是会运行(因为生成了abcdef目录)!

父进程退出,子进程被init领养,继续运行,这是正常的

而前一个,从名字看明显是一个守护进程,id=3803的是会话首进程,也是进程组的组长,KILL掉它,会导致SIGHUP发送给该进程组的每一个进程(就是所有父进程为3803的那些),默认情况下,SIGHUP会终止进程,所以全没了.

详细情况参考APUE2,中文译名是(第二版),非常好的一本书,第9章(进程关系),第10章(信号),第13章(守护进程)对这个问题讲的非常清楚。

意思是守护进程和普通进程在kill时是有区别的,只有守护进程是父进程被kill,子进程就自动消亡,普通进程的父进程被kill掉,被init进程领养。

其实基本一样的,但小有区别.
首先要清楚会话,进程组,控制终端这几个概念.
所有进程都是属于一个进程组的,而进程组又属于一个会话.
普通的进程所属的会话有控制终端,守护进程所属会话没有控制终端.

普通会话的首进程,同时也是建立与控制终端联系的进程,在它被KILL掉时,会向前台进程组发送SIGHUP信号.默认情况下,接收到SIGHUP的进程会被终止.此时后台进程组不受影响.

守护进程的会话,因为没有控制终端,所以就没有前后台进程组之分,会话首进程同时也是进程组组长.它被KILL掉会向该组每个进程发送SIGHUP,导致组中进程被中止.

第二个试验,一个脚本掉另一个脚本的行为,创建了一个新的进程组,脚本A是进程组组长,但却不是所在会话的首进程或控制进程,所以它被KILL掉,不影响同组的进程(脚本B),此时init进程会自动领养脚本B所在进程,并在它运行到结束时回收它所占用的资源.

可以用ps -eo pid,ppid,pgrp,session,comm跑一下.
对于第一种情况,就是守护进程,应该会发现那一堆进程的session(会话ID)和pgrp(组ID)都一样且是相同的,而且正好等于子进程的ppid,同时也是你KILL掉那个进程的pid.这样可以证实你KILL掉的是会话首进程.

对于第二种情况,你会发现,进程A和B,session和pgrp是一样的,但两者却并不相同,session的值虽无法确定,但pgrp却应该正好是进程A的pid,这说明了进程A是组长但却不是会话首进程,所以KILL掉它不会导致子进程被结束.
阅读(1077) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~