当前位置:嗨网首页>书籍在线阅读

04-可中断和不可中断的进程睡眠状态

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

22.3 可中断和不可中断的进程睡眠状态

前文曾指出,SIGKILL和SIGSTOP信号对进程的作用是立竿见影的。对于这一论断,此处要加入一条限制。内核经常需要令进程进入休眠,而休眠状态又分为两种。

  • TASK_INTERRUPTIBLE:进程正在等待某一事件。例如,正在等待终端输入,等待数据写入当前的空管道,或者等待System V信号量值的增加。进程在该状态下所耗费的时间可长可短。如果为这种状态下的进程产生一个信号,那么操作将中断,而传递来的信号将唤醒进程。ps(1)命令在显示处于TASK_INTERRUPTIBLE状态的进程时,会将其STAT(进程状态)字段标记为字母S。
  • TASK_UNINTERRUPTIBLE:进程正在等待某些特定类型的事件,比如磁盘I/O的完成。如果为这种状态下的进程产生一个信号,那么在进程摆脱这种状态之前,系统将不会把信号传递给进程。ps(1)命令在显示处于TASK_UNINTERRUPTIBLE状态的进程时,会将其STAT字段标记为字母D。

因为进程处于TASK_UNINTERRUPTIBLE状态的时间通常转瞬即逝,所以系统在进程脱离该状态时传递信号的现象也不易于被发现。然而,在极少数情况下,进程可能会因硬件故障、NFS问题或者内核缺陷而在该状态下保持挂起。这时,SIGKILL将不会终止挂起进程。如果问题诱因无法得到解决,那么就只能通过重启系统来消灭该进程。

大多数UNIX系统实现都支持TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE状态。从内核2.6.25开始,Linux加入第三种状态来解决上述挂起进程的问题。

  • TASK_KILLABLE:该状态类似于TASK_UNINTERRUPTIBLE,但是会在进程收到一个致命信号(即一个杀死进程的信号)时将其唤醒。在对内核代码的相关部分进行改造后,就可使用该状态来避免各种因进程挂起而重启系统的情况。这时,向进程发送一个致命信号就能杀死进程。为使用TASK_KILLABLE而进行代码改造的首个内核模块是NFS。