Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4273918
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: LINUX

2011-12-11 19:21:18


简单 内核定时器 驱动实现 PC机 中 set_current_state(TASK_INTERRUPTIBLE) 讲解
========================================================================
2.6.35内核
进程状态定义:include/linux/sched.h
  1. 182#define TASK_RUNNING 0
  2.  183#define TASK_INTERRUPTIBLE 1
  3.  184#define TASK_UNINTERRUPTIBLE 2
  4.  185#define __TASK_STOPPED 4
  5.  186#define __TASK_TRACED 8
  6.  187/* in tsk->exit_state */
  7.  188#define EXIT_ZOMBIE 16
  8.  189#define EXIT_DEAD 32
  9.  190/* in tsk->state again */
  10.  191#define TASK_DEAD 64
  11.  192#define TASK_WAKEKILL 128
  12.  193#define TASK_WAKING 256
  13.  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();


阅读(10397) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~