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会终止进程,所以全没了.
详细解释:
所有进程都是属于一个进程组的,而进程组又属于一个会话.
普通的进程所属的会话有控制终端,守护进程所属会话没有控制终端.
普通会话的首进程,同时也是建立与控制终端联系的进程,在它被KILL掉时,会向前台进程组就(a.sh)发送SIGHUP信号.默认情况下,接收到SIGHUP的进程会被终止.此时后台进程组(b.sh)不受影响.
守护进程的会话,因为没有控制终端,所以就没有前后台进程组之分,会话首进程同时也是进程组组长.它被KILL掉会向该组每个进程发送SIGHUP,导致组中进程被中止.
第二个试验,一个脚本调用另一个脚本的行为,创建了一个新的进程组,脚本a.sh是进程组组长,但却不是所在会话的首进程或控制进程,所以它被KILL掉,不影响同组的进程(b.sh),此时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掉它不会导致子进程被结束.
[root@qht2 ~]# ps -eo pid,ppid,pgrp,session,comm
  PID  PPID  PGRP  SESS COMMAND
 1     0     1      1   init
  ***

 3621     1  3621  3621 httpd
 3626  3621  3621  3621 httpd
 3627  3621  3621  3621 httpd
 3628  3621  3621  3621 httpd
 3629  3621  3621  3621 httpd
 3630  3621  3621  3621 httpd
 3631  3621  3621  3621 httpd
 3632  3621  3621  3621 httpd
 3633  3621  3621  3621 httpd
 3643  3574  3643  3574 a.sh
 3644  3643  3643  3574 b.sh
 3645  3644  3643  3574 sleep
 3646  3571  3646  3646 bash
 3674  3646  3674  3646 ps
[root@qht2 ~]#

转自:http://biancheng.dnbcw.info/linux/300534.html
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在操作系统中,进程是正在执行的程序,它们拥有一定的资源和状态。有时候,我们需要终止一个进程,例如当它运行不正常或者占用了过多的资源等情况。通常我们会用kill命令来终止进程,但有些情况下,kill命令无法杀死进程。此时,我们可以采取以下解决方法: 1. 使用kill -9命令:在一般情况下,kill命令发送一个信号给进程,让它在接收信号后自行终止。但有些进程可能会忽略该信号,导致无法终止。此时,可以使用kill -9命令,它会强制终止进程,即无条件地将进程杀死。但需要注意,这种方法可能会使进程无法正常地释放资源和清理状态,可能会导致其它问题。 2. 使用kill -SIGKILL命令:与kill -9类似,SIGKILL是一个特别的终止信号,它也可以强制终止进程。但它不同kill -9的是,SIGKILL会让操作系统立即释放该进程占用的全部资源,包括内存、文件描述符等。因此,如果你需要释放资源并重置系统状态,可以考虑使用kill -SIGKILL命令。 3. 使用pstree命令:有些进程可能是由其它进程fork出来的子进程,因此,它们可能会受到进程的保护而无法被kill命令终止。这时候,我们可以使用pstree命令查看进程树,找到该进程进程,并终止它。一般而言,这种方法较为可靠,不会对系统造成太多的影响。 总之,杀进程的方法有很多种,但需要注意的是,我们应该根据具体情况选择不同的方法,并尽量避免使用强制终止命令,以免引起其它的问题。同时,我们也应该注意保护好自己的系统,防止恶意进程以及病毒占用系统资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值