linux sleep实现源码,linux0.11源码分析-sleep_on与wake_up

sleep_on

如果一个资源没有加锁,就表示还没有被使用,一旦加上锁后,在没有解锁前,其他进程想要使用该资源就要释放cpu等待了。注意执行到schedule()方法时,下面的代码就不会执行了,需要等待调度才能运行,CPU会将该进程的状态保存到进程的TSS中,包括当前进程执行到的位置信息,等待下一次调度后,该进程还有从该位置继续执行,也就执行schedule()方法后面的代码。理解这句话是很重要的,要不然,后面讲解是如何唤醒的过程,就不那么容易理解。

kernel/sched.c

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;

}

复制代码

struct task_struct *current = &(init_task.task); // 当前任务指针(初始化指向任务0)

复制代码

current表示当前CPU正在运行的进程,初始化的时候指向进程0。

现在假设有3个进程T1、T2、T3、T4来抢夺资源,T1先抢到,T1将该资源上锁(lock)。

6082338f2dfc99cd6b0be87556cdcdb4.png

T1还没有使用完该资源,T2也抢到该资源,但是资源已经被上锁,T2进入sleep_on。变量wait存的是一个地址,使用该地址可以找到进程。变量p存的也是一个地址,使用该地址就可以找到变量wait,那么*p就表示变量wait中的地址。

bbab45d7258e1d34ea36c404c03ce239.png

T2进入sleep_on,把在当前资源上等待的进程给tmp,此时资源上还没有等待进程,因为T1是第一个抢到的,抢到后就锁住。T2抢到后发现被锁,T2进入等待,那么此时这个tmp里面保存着NULL地址,,current就表示的是当前进程T2,接下来*p = current就是把变量wait中的值(地址)修改成current,即T2的地址。注意此时T2只能执行到schedule()方法,需要等待唤醒调度后才能继续执行。

T3进入sleep_on,把在当前资源上等待的进程给tmp,此时的wait是有值的,即T2的地址,然后wait又被重新赋值为T3的地址,与T2一样,schedule()执行完后,就等着了。

T4进入sleep_on,把在当前资源上等待的进程给tmp,此时的wait就是T3的地址,然后wait又被重新赋值为T4的地址,与T3一样,schedule()执行完后,也等着了。

f20f0e183ec69f4387db9a0b3b58759f.png

wake_up

T1使用完资源后,开始解锁,唤醒等待在该资源上的进程,T4是最后抢到的,资源上的wait就是T4的地址,*p就是最后一个sleep_on的进程,即T4,接着把T4进程的状态修改为可运行状态,然后等待调度。

接下来就是一股骚操作了~😅,现在T4被调度上CPU,开始运行,那么就会继续沿着sleep_on 中schedule()方法的位置运行,把tmp的状态修改为可运行状态,即T3准备运行。进程会不断循环检资源有没有被锁住。假如T4被唤醒后,又要执行调度把T3唤醒,接着又调度把T2唤醒,现在T1使用完了资源,T2、T3、T4都被唤醒,3个进程又开始公平的抢资源了。

while (bh->b_lock)

sleep_on(&bh->b_wait);

bh->b_lock=1;

复制代码

kernel/sched.c

void wake_up(struct task_struct **p)

{

if (p && *p) {

(**p).state=0; // 置为就绪(可运行)状态TASK_RUNNING.

*p=NULL;

}

}

复制代码

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值