sleep_on()用于进程睡眠。


http://blog.csdn.net/wu5795175/article/details/9156535
sleep_on()用于进程睡眠。

其原型为

void sleep_on(struct task_struct **p);

比如某个资源是互斥的,当资源被某一个进程占用时,其他进程便无法访问此资源。

假设资源结构为

struct __xxx_resource

{

       struct resource *rs;
       struct task_struct *wait;
       ....

}xxx_resource;

那么若某进程无法得到资源,其使用
sleep_on(&wait) 在资源的wait队列上睡眠,注意到这里的wait只是指针变量,那么多个进程调用sleep_on()是如何形成所谓的wait队列呢?以下是我的一些理解。
sleep_on()函数原型如下

void sleep_on(struct task_struct **p)
{
   struct task_struct *tmp;

   if (!p)
      return;
   if (current == &(init_task.task))
      panic("task[0] trying to sleep");
   tmp = *p; 
   *p = current;
   current->state = TASK_UNINTERRUPTIBLE;
   schedule();
   if (tmp)
      tmp->state=0;
}
函数流程比较简单,先做了一些基本的判断,然后使用一个tmp变量指向*p,*p指向当前的进程,设置进程标志为TASK_UNINTERRUPTIBLE即不可中断睡眠,随后就执行schedule()调度其他进程运行,当本进程恢复运行时,设置tmp->state为0即TASK_RUNNING。

让我们用例子来理解sleep_on()
假设有2个进程A,B都无法访问资源,只能执行sleep_on(&wait)进行睡眠。
1. 进程A执行sleep_on(&wait),进入睡眠,tmp -> wait'(NULL),wait'' -> 进程A task_struct
2. 进程B执行sleep_on(&wait),进入睡眠,tmp -> wait'',wait''' -> 进程B task_struct

wait上标表示wait值的不同。
可以看到wait始终指向的是最后一个执行sleep_on()的进程task_struct。

理解的关键在于:所有的进程共用一个公有的wait变量(因为资源只有一个),然而内部的tmp变量是进程私有的,(tmp变量在栈中分配),便是私有的tmp和公有的wait形成了等待队列,而wait可以看成是等待队列的第一个成员,tmp则指向等待队列的第二个成员。

当资源被释放,使用wake_up(&wait)唤醒等待队列上的睡眠进程,过程则如下
1. wait指向进程B的task_struct,则进程B被唤醒。
2. 进程B唤醒后,执行if (tmp) tmp->state = 0,进程B上下文中的tmp是指向进程A的task_struct,则进程A被唤醒。
3. 进程A被进程B唤醒。

可以发现,调用了wake_up(&wait)之后,在等待队列上睡眠的所有进程都被唤醒了,以一种“链式”的方式。

http://blog.csdn.net/wu5795175/article/details/9156535

sleep_on()用于进程睡眠。

其原型为

void sleep_on(struct task_struct **p);

比如某个资源是互斥的,当资源被某一个进程占用时,其他进程便无法访问此资源。

假设资源结构为

struct __xxx_resource

{

       struct resource *rs;
       struct task_struct *wait;
       ....

}xxx_resource;

那么若某进程无法得到资源,其使用
sleep_on(&wait) 在资源的wait队列上睡眠,注意到这里的wait只是指针变量,那么多个进程调用sleep_on()是如何形成所谓的wait队列呢?以下是我的一些理解。
sleep_on()函数原型如下

void sleep_on(struct task_struct **p)
{
   struct task_struct *tmp;

   if (!p)
      return;
   if (current == &(init_task.task))
      panic("task[0] trying to sleep");
   tmp = *p; 
   *p = current;
   current->state = TASK_UNINTERRUPTIBLE;
   schedule();
   if (tmp)
      tmp->state=0;
}
函数流程比较简单,先做了一些基本的判断,然后使用一个tmp变量指向*p,*p指向当前的进程,设置进程标志为TASK_UNINTERRUPTIBLE即不可中断睡眠,随后就执行schedule()调度其他进程运行,当本进程恢复运行时,设置tmp->state为0即TASK_RUNNING。

让我们用例子来理解sleep_on()
假设有2个进程A,B都无法访问资源,只能执行sleep_on(&wait)进行睡眠。
1. 进程A执行sleep_on(&wait),进入睡眠,tmp -> wait'(NULL),wait'' -> 进程A task_struct
2. 进程B执行sleep_on(&wait),进入睡眠,tmp -> wait'',wait''' -> 进程B task_struct

wait上标表示wait值的不同。
可以看到wait始终指向的是最后一个执行sleep_on()的进程task_struct。

理解的关键在于:所有的进程共用一个公有的wait变量(因为资源只有一个),然而内部的tmp变量是进程私有的,(tmp变量在栈中分配),便是私有的tmp和公有的wait形成了等待队列,而wait可以看成是等待队列的第一个成员,tmp则指向等待队列的第二个成员。

当资源被释放,使用wake_up(&wait)唤醒等待队列上的睡眠进程,过程则如下
1. wait指向进程B的task_struct,则进程B被唤醒。
2. 进程B唤醒后,执行if (tmp) tmp->state = 0,进程B上下文中的tmp是指向进程A的task_struct,则进程A被唤醒。
3. 进程A被进程B唤醒。

可以发现,调用了wake_up(&wait)之后,在等待队列上睡眠的所有进程都被唤醒了,以一种“链式”的方式。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值