/* 这是一个非常复杂的函数: 该函数与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;}
}
详细解决方案
linux0.11 sleep_on函数说明
热度:21 发布时间:2023-12-15 12:02:29.0
相关解决方案
- linux0.11内核代码有段内嵌汇编理解不能,
- Linux0.11源码研读(1)(一点废话)
- linux0.11运行环境2021.10.10(ubuntu)
- Linux0.11 实验四 进程运行轨迹跟踪与统计
- linux0.11 sleep_on函数说明
- linux0.11_系统调用
- linux0.11内核完全剖析 - ramdisk.c
- linux0.11内核完全剖析 - hd.c
- linux0.11内核完全剖析 - 块设备驱动程序
- linux0.11内核完全剖析 - vsprintf.c
- linux0.11内核完全剖析 - sys.c
- linux0.11内核完全剖析- fork.c
- linux0.11内核完全剖析- exit.c
- linux0.11内核完全剖析- sched.c
- linux0.12内核---内存分页与线性地址到物理内存的转换
- linux0.12内核---关于内存寻址与4k边界对齐