当前位置: 代码迷 >> 综合 >> linux0.11 sleep_on函数说明
  详细解决方案

linux0.11 sleep_on函数说明

热度:21   发布时间:2023-12-15 12:02:29.0
/* 这是一个非常复杂的函数: 该函数与wake_up配合使用,我们用一个例子来说明这个复杂的问题 sleep_on(&inode->i_wait); 比如有任务在等待资源inode->i_wait,如果这个资源是NULL,也就是说,没有任何人在使用这个东西,那么就无需等待,如果这个队列里面有东西,那么就存在tmp里面,tmp此时指向原等待队列头,值得注意的是,这个地方,tmp是局部变量,而p是全局的。 所有进程共用p , 每个进程都有自己的tmp讲本进程设置为TASK_UNINTERRUPTIBLE,也就是说调度不会再调度这个进程了,必须要通过wake_up才能重新回来,继续往下跑。假设现在有3个任务,A,B,C都在等一个资源。调用sleep_on的时间顺序为, C,B,A 此时inode->i_wait的队列头部是A,后来者,在队头。此时wake_up 将这个队头 置为就绪态,A为就绪态,那么A就可以重新参与调度, 当A被调度的时候,A被唤醒,在A进程中的tmp指向B,把B设置为就绪态,让B重新参与调度。然后A继续往下运行,直到时间到或者发生重新调度。 当B被调度的时候,B被唤醒,在B进程中的tmp指向C,把C设置为就绪态,让C重新参与调度。然后B继续往下运行...就这样,这个奇怪的唤醒队列,就这样正确的工作了。这个队列是隐蔽的,这个队列里面的next任务,是存在不同进程的局部变量的,是夸进程的。*///当一个进程所需要的资源正忙,暂时切换出去。
void sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;if (!p)return;if (current == &(init_task.task)) //进程0不能睡眠。panic("task[0] trying to sleep");tmp = *p;*p = current;current->state = TASK_UNINTERRUPTIBLE;//不可中断,这个任务不会在就绪态,不参与本轮调度。schedule();//这个任务重新被唤醒,才往下执行。这里是嵌套使用的,if (tmp)tmp->state=TASK_RUNNING;//置为就绪态,先等的任务先执行。
}void wake_up(struct task_struct **p)
{
    if (p && *p) {
    (**p).state=TASK_RUNNING;//置为就绪态。*p=NULL;}
}