========================================================================
2.6.35内核
进程状态定义:include/linux/sched.h
- 182#define TASK_RUNNING 0
-
183#define TASK_INTERRUPTIBLE 1
-
184#define TASK_UNINTERRUPTIBLE 2
-
185#define __TASK_STOPPED 4
-
186#define __TASK_TRACED 8
-
187/* in tsk->exit_state */
-
188#define EXIT_ZOMBIE 16
-
189#define EXIT_DEAD 32
-
190/* in tsk->state again */
-
191#define TASK_DEAD 64
-
192#define TASK_WAKEKILL 128
-
193#define TASK_WAKING 256
-
194#define TASK_STATE_MAX 512
一个介绍内核进程文章:
本文摘自 深入理解linux内核 第三版 p87 进程状态
进程描述符中的state字段描述了进程当前所处的状态。它由一组标志组成,其中每个标志描述符一种可能的进程状态。在当前的Linux版本中,这些状态是互斥的,因此,严格意义上说,只能设置一种状态;其余多为标志将被清除。下面是纪念册可能的状态
可运行状态 TASK_RUNNING
进程要么在CPU上执行,要么准备执行
可中断的等待状态 TASK_INTERRUPTIBLE
进程被挂起(睡眠),直到某个条件变为真。产生一个硬件中断,释放进程正在等待的系统资源,或传递一个信号都是可以唤醒进程的条件(把进程的状态放回到TASK_RUNNING)
不可中断的等待状态(TASK_UNINTERRUPTIBLE)
与可中断的等待状态类似,但有一个例外,把信号传递到睡眠进程不能改变它的状态。这种状态很少用到,但在一些特定的情况下(进程必须等待,直到一个不能被中断的事件发生),这种状态时很有用的。例如:当进程打开一个设备文件,其相应的设备驱动程序开始探测相应的硬件设备时会用到这种状态。探测完成以前,设备驱动程序不能被中断,否则,硬件设备会处于不可预知的状态。
暂停状态 TASK_STOPPED
进程的执行被暂停。当进程接收到SIGSTOP SIGTSTP SIGTTIN 或 SIGTTOU信号后,进入暂停状态
跟踪状态 TASK_TRACED
进程的执行已由debugger程序暂停。当一个进程被另一个进程监控时(例如,debugger执行ptrace()系统调用监控一个测试程序),任何信号都可以把这个进程至于TASK_TRACED状态
还有两个进程状态既可以存放在进程描述符的state字段中,也可以存放在exit_state字段中。从这两个字段的名称可以看出,只有当进程的执行被终止时,进程的状态才会变为这两种状态中的一种
僵死状态 EXIT_ZOMBIE
进程的执行被终止,但是,父进程还没有发布wait4() 或 waitpid()系统调用来返回有关死亡进程的信息。发布wait()类系统调用前,内核不能丢弃。包含在死进程描述符中的数据,因为父进程可能还需要它。
僵死撤销状态 EXIT_EDAD
最终状态,由于父进程刚发出wait4() 或 waitpid()系统调用,因而进程由系统删除。为了防止其他进程执行线程在同一个进程上夜执行wait()类系统调用(这是一种竞争条件),而把进程的状态由僵死状态改为僵死撤销状态。
state字段的值通常用一个简单的复制语句设置。
p->state=TASK_RUNNING;
内核也使用set_task_state和 set_current_stae宏,:他们分别设置指定进程的状态和当前执行进程的状态。此外,这些宏确保编译程序或CPU控制单元不能把赋值操作与其他指令混合。混合指令的顺序有时会导致灾难性的后果。
set_current_state() 的使用在驱动程序中,进程睡眠往往通过 3 个步骤进行:1. 将进程加入等待队列中。2. 然后使用 set_current_state() 来设置进程的状态,设置的状态为 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUTIBLE 。3. 上面的设置完后,我们就要放弃处理器了。但在放弃处理器之前,还有一件重要的事情需要做:检查睡眠等待的条件。如果不检查,如果此时条件正好变为真,那么就漏掉了继续运行的机会,从而会睡眠更长的时间。就好比如,你在等一辆车,你觉得车还没来,你很困并就打算先睡一会儿,此时有一辆车刚好过来了,你睡眼朦胧的并没打算睁开眼睛去看一下,结果得花更长的时间来等下一趟。所以,一般在睡前需要类似的动作:
set_current_state(TASK_UNINTERRUPTIBLE);
if (do_i_need_to_sleep())
schedule();
阅读(10676) | 评论(0) | 转发(0) |