linux僵尸进程&&进程进入不可中断休眠状态

原创 2016年06月28日 11:40:03


1.平台Hi3536发现某些进程使用(kill -9)杀不掉

ps查看指令为      ps -o pid,ppid,stat,comm

stat:
     D    不可中断     Uninterruptible sleep (usually IO)
                     R    正在运行,或在队列中的进程
                     S    处于休眠状态
                     T    停止或被追踪
                     Z    僵尸进程
                     W    进入内存交换(从内核2.6开始无效)
                     X    死掉的进程
                     <    高优先级
                     N    低优先级
                     L    有些页被锁进内存
                     s    包含子进程
                     +    位于后台的进程组;
                     l    多线程,克隆线程

其中程序进入僵尸进程和不可中断的休眠状态进程都是依靠kill -9杀不掉的。


2.僵尸进程产生原因,危害,规避办法及补救办法:

产生原因:

在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程,无法正常结束,此时即使是root身份kill -9也不能杀死僵尸进程。

僵尸进程危害:

在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。

僵尸进程的规避方案

⒈父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
⒋ 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。

补救办法

杀死僵尸进程的父进程(僵尸进程的父进程必然存在),僵尸进程成为"孤儿进程",过继给1号进程init,init始终会负责清理僵尸进程。

不可中断的休眠状态进程产生原因,解决办法

产生原因:
这种状态出现的情形主要是等待关键资源或者等待系统调用结束的时候会出现。进程处于此状态时,不能响应异步信号,不能被kill -9等信号结束,只能等待wake_up()。不可中断睡眠,只能被如硬件中断、正在等待的资源被释放等唤醒,对其他的进程传递不响应。
不可中断睡眠状态与可中断睡眠状态类似,但是它有一个例外,那就是把信号传递到这种睡眠 状态的进程不能改变它的状态,也就是说它不响应信号的唤醒。不可中断睡眠状态一般较少用到,但在一些特定情况下这种状态还是很有用的,比如说:进程必须等 待,不能被中断,直到某个特定的事件发生。



题外:

一个进程对kill -9不响应的有两种情况

  1. 未接受到信号或者没有得到分配的时间来完成自己退出所需要的步骤,比如CPU100%时,多等一些时间应该会自动中止

  2. 进程处于IO等待中这时候屏蔽了信号接收自然不会对KILL作出响应,除非IO的请求得到响应,要判断这种情况你可以看 ps aux|grep vi看看进程状态, 如果是 D 那就是了,这个情乱会麻烦一点因为它需要请求的IO得到满足或者被拒绝,而系统没有给与明确的答复他就一直干等着,根据你的描述你需要看这个打开的文件的情况,如果是nfs,那么建议在添加挂载选项为 bg,hard,intr避免这个问题的重现,如果是本地文件你需要察看硬盘或者存储阵列卡是否有问题但是要杀死这个进程却需要重启来解决


另外:该进程处于"kernel mode"(核心态)且在等待不可获得的资源。处于核心态的进程忽略所有信号处理,因此对于这些一直处于核心态的进程只能通过重启系统实现。进程在unix/linux中会处于两种状态,即用户态和核心态。只有处于用户态的进程才可以用“kill”命令将其终止。








相关文章推荐

中断不可睡眠的一些理解

LINUX中到是有中断还没有完全返回就调用schedule()而睡眠过去的例子。 可以猜是哪里。 我觉得,中断和异常不同,中断是异步的,异常和系统调用是同步的。...

关于LINUX在中断(硬软)中不能睡眠(down)的真正原因

原帖地址:http://bbs.chinaunix.net/thread-2115820-1-1.html 这里引用个人认为比较OK的解析: 呵呵,我最喜欢这种讨论了。先来献丑了,说说我的看法。 ...

为什么在Linux中断服务程序中不能睡眠

最近本人在实现TILE CPU架构上的中断子系统,抽出一点时间来仔细研究了下Linux上的中断设计。对内核有所了解的人都知道,在Linux中断ISR中不能睡眠,但是为什么不能睡眠呢? 其中一个比较流...

Linux进程状态:D

转自:http://spazzzz.blog.51cto.com/2707720/603028 man ps 中描述D状态是Uninterruptible Sleep Linux进程有两种睡...
  • djskl
  • djskl
  • 2015年04月05日 12:43
  • 738

Linux休眠与唤醒

在Linux中,休眠主要分三个主要的步骤:(1)冻结用户态进程和内核态任务;(2)调用注册的设备的suspend的回调函数;(3)按照注册顺序休眠核心设备和使CPU进入休眠态。      冻结进程是内...

为什么中断不能睡眠

这个问题有很多人问过,我看了下Linux得内核代码,原因如下:(当然我不能保证一定对,如果有牛人理解得更好,欢迎指正) 1、 中断处理的时候,不应该发生进程切换,因为在中断context中,唯一...
  • mihouge
  • mihouge
  • 2015年03月11日 14:29
  • 1541

Linux进程状态解析之R、S、D、T、Z、X

Linux是一个多用户,多任务的系统,可以同时运行多个用户的多个程序,就必然会产生很多的进程,而每个进程会有不同的状态。Linux进程状态:R (TASK_RUNNING),可执行状态。只有在该状态的...
  • nilxin
  • nilxin
  • 2012年04月08日 14:00
  • 17831

USB OTG驱动分析(一)

转自 http://blog.csdn.net/ling1874/article/details/5758883 功能都是因为需求 存在的,举个最简单的需求,原来 MP3 想传送一个歌曲都得通过电脑...
  • adazone
  • adazone
  • 2014年12月23日 10:34
  • 608

《Linux那些事儿之我是USB》我是U盘(12)梦开始的地方

对于整个usb-storage模块,usb_stor_init()函数是它的开始,然而,对于U盘驱动程序来说,它真正驱使U盘工作却是始于storage_probe()函数。 两条平行线只要相交,就注...

linux中的僵尸进程

  • 2012年05月21日 11:26
  • 6KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux僵尸进程&&进程进入不可中断休眠状态
举报原因:
原因补充:

(最多只允许输入30个字)