- 浏览: 1999402 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (651)
- ACE (35)
- BAT (9)
- C/C++ (116)
- fast-cgi (14)
- COM (27)
- python (59)
- CGI (4)
- C# (2)
- VC (84)
- DataBase (29)
- Linux (96)
- P2P (6)
- PHP (15)
- Web (6)
- Memcached (7)
- IME输入法 (11)
- 设计模式 (2)
- 搜索引擎 (1)
- 个人情感 (4)
- 笔试/面试 (3)
- 一亩三分地 (33)
- 历史 (2)
- 地理 (1)
- 人物 (3)
- 经济 (0)
- 不仅仅是笑哦 (43)
- 小故事大道理 (2)
- http://www.bjdsmyysjk120.com/ (0)
- http://www.bjdsmyy120.com/ (0)
- 它山之石可以攻玉 (15)
- 大学生你关注些什么 (28)
- 数据恢复 (1)
最新评论
-
luokaichuang:
这个规范里还是没有让我明白当浏览器上传文件时,STDIN的消息 ...
FastCGI规范 -
effort_fan:
好文章!学习了,谢谢分享!
com技术简介 -
vcell:
有错误os.walk(strPath)返回的已经是全部的文件和 ...
通过python获取目录的大小 -
feifeigd:
feifeigd 写道注意:文章中的CPP示例第二行 #inc ...
ATL入门:利用ATL编写简单的COM组件 -
feifeigd:
注意:文章中的CPP示例第二行 #include " ...
ATL入门:利用ATL编写简单的COM组件
- 摘要: Linux系统中进程有很多种状态,前面我们说了R、S、D三种状态,还有另外的三种状态,这里我们一并说一下,补全前面的文章。
- 标签: Linux进程状态
上面一篇文章中我们介绍了Linux进程的R、S、D三种状态,这里接着上面的文章介绍另外三个状态。
Linux进程状态:T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态。
向进程发送一个SIGSTOP信号,它就会因响应该信号而进入TASK_STOPPED状态(除非该进程本身处于
TASK_UNINTERRUPTIBLE状态而不响应信号)。(SIGSTOP与SIGKILL信号一样,是非常强制的。不允许用户进程通过
signal系列的系统调用重新设置对应的信号处理函数。)
向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态。
当进程正在被跟踪时,它处于TASK_TRACED这个特殊的状态。“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。比如在 gdb中对被跟踪的进程下一个断点,进程在断点处停下来的时候就处于TASK_TRACED状态。而在其他时候,被跟踪的进程还是处于前面提到的那些状 态。
对于进程本身来说,TASK_STOPPED和TASK_TRACED状态很类似,都是表示进程暂停下来。
而TASK_TRACED状态相
当于在TASK_STOPPED之上多了一层保护,处于TASK_TRACED状态的进程不能响应SIGCONT信号而被唤醒。只能等到调试进程通过
ptrace系统调用执行PTRACE_CONT、PTRACE_DETACH等操作(通过ptrace系统调用的参数指定操作),或调试进程退出,被调
试的进程才能恢复TASK_RUNNING状态。
Linux进程状态:Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。
进程在退出的过程中,处于TASK_DEAD状态。
在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,故称为僵尸。
之所以保留task_struct,是因为task_struct里面保存了进程的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。比如在shell中,$?变量就保存了最后一个退出的前台进程的退出码,而这个退出码往往被作为if语句的判断条件。
当
然,内核也可以将这些信息保存在别的地方,而将task_struct结构释放掉,以节省一些空间。但是使用task_struct结构更为方便,因为在
内核中已经建立了从pid到task_struct查找关系,还有进程间的父子关系。释放掉task_struct,则需要建立一些新的数据结构,以便让
父进程找到它的子进程的退出信息。
父进程可以通过wait系列的系统调用(如wait4、waitid)来等待某个或某些子进程的退出,并获取它的退出信息。然后wait系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉。
子进程在退出的过程中,内核会给其父进程发送一个信号,通知父进程来“收尸”。这个信号默认是SIGCHLD,但是在通过clone系统调用创建子进程时,可以设置这个信号。
通过下面的代码能够制造一个EXIT_ZOMBIE状态的进程:
#include void main() { if (fork()) while(1) sleep(100); }
编译运行,然后ps一下:
kouu@kouu-one:~/test$ ps -ax | grep a\.out 10410 pts/0 S+ 0:00 ./a.out 10411 pts/0 Z+ 0:00 [a.out] 10413 pts/1 S+ 0:00 grep a.out
只要父进程不退出,这个僵尸状态的子进程就一直存在。那么如果父进程退出了呢,谁又来给子进程“收尸”?
当进程退出的时候,会将它的所有子进程都托管给别的进程(使之成为别的进程的子进程)。托管给谁呢?可能是退出进程所在进程组的下一个进程(如果存在的话),或者是1号进程。所以每个进程、每时每刻都有父进程存在。除非它是1号进程。
1号进程,pid为1的进程,又称init进程。
linux系统启动后,第一个被创建的用户态进程就是init进程。它有两项使命:
1、执行系统初始化脚本,创建一系列的进程(它们都是init进程的子孙);
2、在一个死循环中等待其子进程的退出事件,并调用waitid系统调用来完成“收尸”工作;
init进程不会被暂停、也不会被杀死(这是由内核来保证的)。它在等待子进程退出的过程中处于TASK_INTERRUPTIBLE状态,“收尸”过程中则处于TASK_RUNNING状态。
Linux进程状态:X (TASK_DEAD - EXIT_DEAD),退出状态,进程即将被销毁。
而进程在退出过程中也可能不会保留它的task_struct。比如这个进程是多线程程序中被detach过的进程(进程?线程?参见《linux
线程浅析》)。或者父进程通过设置SIGCHLD信号的handler为SIG_IGN,显式的忽略了SIGCHLD信号。(这是posix的规定,尽管
子进程的退出信号可以被设置为SIGCHLD以外的其他信号。)
此时,进程将被置于EXIT_DEAD退出状态,这意味着接下来的代码立即就会将该进程彻底释放。所以EXIT_DEAD状态是非常短暂的,几乎不可能通过ps命令捕捉到。
进程的初始状态
进程是通过fork系列的系统调用(fork、clone、vfork)来创建的,内核(或内核模块)也可以通过kernel_thread函数创
建内核进程。这些创建子进程的函数本质上都完成了相同的功能——将调用进程复制一份,得到子进程。(可以通过选项参数来决定各种资源是共享、还是私有。)
那么既然调用进程处于TASK_RUNNING状态(否则,它若不是正在运行,又怎么进行调用?),则子进程默认也处于TASK_RUNNING状态。
另外,在系统调用调用clone和内核函数kernel_thread也接受CLONE_STOPPED选项,从而将子进程的初始状态置为 TASK_STOPPED。
进程状态变迁
进程自创建以后,状态可能发生一系列的变化,直到进程退出。而尽管进程状态有好几种,但是进程状态的变迁却只有两个方向——从TASK_RUNNING状态变为非TASK_RUNNING状态、或者从非TASK_RUNNING状态变为TASK_RUNNING状态。
也
就是说,如果给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNING状态),
然后再响应SIGKILL信号而退出(变为TASK_DEAD状态)。并不会从TASK_INTERRUPTIBLE状态直接退出。
进程从非TASK_RUNNING状态变为TASK_RUNNING状态,是由别的进程(也可能是中断处理程序)执行唤醒操作来实现的。执行唤醒的 进程设置被唤醒进程的状态为TASK_RUNNING,然后将其task_struct结构加入到某个CPU的可执行队列中。于是被唤醒的进程将有机会被 调度执行。
而进程从TASK_RUNNING状态变为非TASK_RUNNING状态,则有两种途径:
1、响应信号而进入TASK_STOPED状态、或TASK_DEAD状态;
2、
执行系统调用主动进入TASK_INTERRUPTIBLE状态(如nanosleep系统调用)、或TASK_DEAD状态(如exit系统调用);或
由于执行系统调用需要的资源得不到满足,而进入TASK_INTERRUPTIBLE状态或TASK_UNINTERRUPTIBLE状态(如
select系统调用)。
显然,这两种情况都只能发生在进程正在CPU上执行的情况下。
发表评论
-
多机器执行ssh脚本
2012-08-30 18:12 2178#!/bin/bash Usage() { ... -
Berkeley DB 使用经验总结
2012-08-27 14:41 3024作者:陈磊 NoSQL是现在互联网Web2.0时代备受 ... -
嵌入式数据库系统Berkeley DB
2012-08-27 14:37 1474前言 UNIX/LINUX平台下的数据库种类非常多 ... -
shell中双引号的误用
2011-05-12 15:02 1127for i in "$LIST" ... -
shell for循环
2011-04-06 15:36 906for i in "1 2 3";do e ... -
shell技巧 除法
2011-03-07 11:34 19127shell计算中使用除法,基本默认上都是整除。 比如: ... -
.bash_profile 文件修改之后不执行
2011-02-16 11:21 1873重新登录 不可能不好用的 除非你是从一个用户su oralc ... -
SecureCRT中文显示乱码的解决方法
2011-02-12 11:38 1294最近开始用SecureCRT登陆linux系统,由于是新手,很 ... -
让putty显示中文
2011-02-11 14:43 1374对于经常在windows下远程ssh到linux的用户而言,p ... -
Linux文件类型全解析
2011-01-04 15:13 1358Linux文件类型全解析 ... -
Linux进程状态解析之R、S、D
2011-01-04 14:54 4832摘要: Linu ... -
shell获取参数
2010-12-31 15:29 4131#!/bin/bash Usage() { ... -
Shell实现cgi接口示例
2010-12-30 14:59 1949ls -l /var/www/cgi-bin/ -rwxrw ... -
shell数组
2010-12-29 16:48 1249shell数组 Bash中还可以使用数 ... -
shell 自动化处理
2010-12-29 15:52 993#!/bin/bash sudo yum instal ... -
Linux用户添加sudoer
2010-12-29 11:37 24877使用sudo可以在以非root用户登录时临时获得root权限, ... -
lsof:一个功能强大的命令
2010-12-24 16:30 1318lsof:一个功能强大的命令 lsof命令的原始功能 ... -
linux 的库操作命令 ar和nm
2010-12-22 20:31 1363当我们的程序中有经 ... -
LINUX查看硬件配置 命令
2010-12-21 18:55 1016常用命令整理如下: 查看主板的序列号: dmidec ... -
awk应用
2010-12-19 16:58 1198a.txt andy 05/99 48311 ...
相关推荐
关于Linux下有哪些进程状态,各种进程状态分别代表什么含义,及其符号
linux下进程状态描述
linux内核源代码深度解析linux内核源代码深度解析linux内核源代码深度解析linux内核源代码深度解析linux内核源代码深度解析linux内核源代码深度解析linux内核源代码深度解析linux内核源代码深度解析linux内核源代码...
1 Linux进程的睡眠和唤醒 ...Linux 中的进程睡眠状态有两种:一种是可中断的睡眠状态,其状态标志位TASK_INTERRUPTIBLE; 另一种是不可中断 的睡眠状态,其状态标志位为TASK_UNINTERRUPTIBLE。可中断
Linux进程init主配置文件etcinittab的解析IT知识
本章将向读者依次解释中断概念,解析Linux中的中断实现机理以及Linux下中断如何被使用。作为实例我们第一将向《i386体系结构》一章中打造的系统加入一个时钟中断;第二将为大家注解RTC中断,希望通过这两个实例可以...
深刻理解Linux进程间通信(IPC) 1 Linux环境进程间通信(一) 3 Linux环境进程间通信(二): 信号(上) 19 Linux环境进程间通信(二): 信号(下) 30 Linux环境进程间通信(三) 40 Linux环境进程间通信(四) 52...
-x——显示当前用户没有控制终端的进程。 -l——使用长(long)格式显示进程信息。 -w——宽行显示,可以使用多个w进行加宽显示。 -e——显示系统内的所有(every)进程(包括用户进程、没有控制终端系统进程)信息。 -f...
Linux进程调度时机 Schedule函数解析
Linux进程间通讯视频教程,包括6个视频教程,非常实用,适合初学者!
某银行的进程池管理代码,,Unix/linux进程池管理
Linux进程调度Linux进程调度策略分析策略分析,
个人文件 进程 linux 个人文件 进程 linux
Linux系统中的进程间通信是典型的虚拟内存系统中的进程间通信:Linux 的进程间通信是不同进程间交换数据的机制。由于Linux系统支持虚拟内 存, 对于每一个进程,系统会为它分配一个单独的进程空间,不同的进程有不同...
LINUX进程管理实验,LINUX中的基本实验
linux进程管理分析
Linux C开发的Linux进程池。 Linux C开发的Linux进程池。 Linux C开发的Linux进程池。 Linux C开发的Linux进程池。
Linux进程调器的设计Linux进程的管与调(十七) 嵌入式Linux中文站Linux进程调度器的设计--Linux进程的管理与调度(十七)分类:新手
linux进程源代码分析
本章主要介绍进程的概念、状态、构成以及Linux进程的相关知识。 掌握进程的概念 掌握进程的描述、状态及转换 理解进程的特征 了解Linux进程的描述及进程通信 掌握进程的同步与互斥,并能灵活运用 理解线程的概念及...