在Linux上如何kill -9进程没有效果​​?

我正在编写一个插件,在您访问网站时自动突出显示文本string。 这就像重点search结果,但自动和许多单词; 它可以用于过敏的人,使得话语真正脱颖而出,例如当他们浏览食物网站时。

但是我有问题。 当我试图closures一个空的,新鲜的FF窗口,它不知何故阻止了整个过程。 当我杀死进程时,所有的窗口消失,但Firefox进程仍然活着(父PID是1,不听任何信号,有大量资源打开,仍然吃CPU,但不会放弃)。

所以有两个问题:

  1. 一个进程如何不听kill -9(既不是用户也不是root)?

  2. 有什么我可以做,但重新启动?

[编辑]这是违规的过程:

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND digulla 16688 4.3 4.2 784476 345464 pts/14 D Mar28 75:02 /opt/firefox-3.0/firefox-bin 

ps -ef | grep firefox相同 ps -ef | grep firefox

 UID PID PPID C STIME TTY TIME CMD digulla 16688 1 4 Mar28 pts/14 01:15:02 /opt/firefox-3.0/firefox-bin 

这是唯一的过程。 正如你所看到的,它不是僵尸,它正在运行! 它不听kill -9,不pipe我是用PID还是名字杀了! 如果我试图与strace连接, strace也挂起,不能被杀害。 也没有输出。 我的猜测是,FF挂在一些内核例程,但是哪个?

[编辑2]基于sigjuice的反馈:

 ps axopid,comm,wchan 

可以向您显示进程挂起的内核例程。 在我的情况下,这个有害的插件是Beagle Indexer(openSUSE 11.1)。 禁用插件后,FF又是一个又快又快乐的狐狸。

正如在OP的评论中指出的, D的进程状态( STAT )表示进程处于“不可中断的hibernate”状态。 在现实世界中,这通常意味着它正在等待I / O,并且不能/不会做任何事情 – 包括死亡 – 直到I / O操作完成。

处于D状态的进程通常只会在运行完成前的几分之一秒内返回到R / S 根据我的经验,如果一个进程陷入D ,最常尝试与无法访问的NFS或其他远程文件系统进行通信,尝试访问发生故障的硬盘驱动器,或者通过片状设备驱动程序使用某些硬件。 在这种情况下,恢复和允许进程死掉的唯一方法是让fs / drive / hardware备份并运行,这样I / O就可以完成,或者放弃并重启系统。 在NFS的特定情况下,挂载也可能最终超时并从I / O操作(带有失败代码)返回,但是这取决于挂载选项,并且NFS挂载被设置为永远等待。

这与僵尸进程是有区别的,僵尸进程的状态为Z

仔细检查父母身份是真的1.如果不是,这是firefox ,首先尝试sudo killall -9 firefox-bin 。 之后,尝试使用sudo killall -9 [process-id]分别查杀特定的进程ID。

一个进程如何不听取kill -9(neiter作为用户还是作为root)?

如果一个进程已经<defunct> ,然后变成一个父亲为1的僵尸 ,你不能手动杀死它; 只有init可以。 僵尸进程已经死了,消失了 – 由于不再是进程,他们失去了被杀的能力,只有一个进程表条目及其相关的退出代码等待收集。 你需要杀死父母,你不能因为显而易见的原因杀死init

在这里看到更多的一般信息。 重启会自然而然地杀死所有的东西。

这个过程是否有可能在你杀死它的时候重新启动(例如通过init)?

你可以很容易地检查。 如果PID在kill -9 PID后是相同的,那么进程没有被终止,但是如果它改变了进程已经被重新启动。

ps -ef | grep firefox; 你可以看到3个进程,全部杀死它们。

 sudo killall -9 firefox 

应该pipe用

编辑:[PID]改为Firefox

你也可以做一个pstree并杀死父母。 这确保你得到整个违规的进程树,而不仅仅是叶。

我最近陷入了Double Fork的陷阱,终于find了我的答案,然后登陆这个页面。 即使问题不一样,症状也是一样的:

  • WYKINWYT:你杀的不是你的想法

基于SNMP守护进程的示例,下面显示了最小testing代码

 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> int main(int argc, char* argv[]) { //We omit the -f option (do not Fork) to reproduce the problem char * options[]={"/usr/local/sbin/snmpd",/*"-f","*/-d","--master=agentx", "-Dagentx","--agentXSocket=tcp:localhost:1706", "udp:10161", (char*) NULL}; pid_t pid = fork(); if ( 0 > pid ) return -1; switch(pid) { case 0: { //Child launches SNMP daemon execv(options[0],options); exit(-2); break; } default: { sleep(10); //Simulate "long" activity kill(pid,SIGTERM);//kill what should be child, //ie the SNMP daemon I assume printf("Signal sent to %d\n",pid); sleep(10); //Simulate "long" operation before closing waitpid(pid); printf("SNMP should be now down\n"); getchar();//Blocking (for observation only) break; } } printf("Bye!\n"); } 

在第一阶段,主进程(7699)启动SNMP守护进程(7700),但是我们可以看到这个现在是Defunct / Zombie 。 除此之外,我们可以看到另一个具有我们指定选项的进程(7702)

 [nils@localhost ~]$ ps -ef | tail root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0] root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1] root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2] root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2] root 7698 729 0 23:11 ? 00:00:00 sleep 60 nils 7699 2832 0 23:11 pts/0 00:00:00 ./main nils 7700 7699 0 23:11 pts/0 00:00:00 [snmpd] <defunct> nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161 nils 7727 3706 0 23:11 pts/1 00:00:00 ps -ef nils 7728 3706 0 23:11 pts/1 00:00:00 tail 

模拟10秒后,我们将尝试杀死我们所知的唯一过程(7700)。 我们最后用waitpid()成功了。 但过程7702仍然在这里

 [nils@localhost ~]$ ps -ef | tail root 7431 2 0 23:00 ? 00:00:00 [kworker/u256:1] root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0] root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1] root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2] root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2] root 7698 729 0 23:11 ? 00:00:00 sleep 60 nils 7699 2832 0 23:11 pts/0 00:00:00 ./main nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161 nils 7751 3706 0 23:12 pts/1 00:00:00 ps -ef nils 7752 3706 0 23:12 pts/1 00:00:00 tail 

给一个字符给getchar()函数后,我们的主进程终止,但是带有pid 7002的SNMP守护进程仍然在这里

 [nils@localhost ~]$ ps -ef | tail postfix 7399 1511 0 22:58 ? 00:00:00 pickup -l -t unix -u root 7431 2 0 23:00 ? 00:00:00 [kworker/u256:1] root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0] root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1] root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2] root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2] root 7698 729 0 23:11 ? 00:00:00 sleep 60 nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161 nils 7765 3706 0 23:12 pts/1 00:00:00 ps -ef nils 7766 3706 0 23:12 pts/1 00:00:00 tail 

结论

我们忽视双叉机制的事实使我们认为杀人行动没有成功。 但实际上我们只是简单地杀了错误的过程!

通过添加-f选项(不(双)叉)都按预期方式