对于linux 0.11版本中睡眠和唤醒函数的理解

本文详细解析了Linux 0.11内核中的sleep_on()和interruptible_sleep_on()函数,阐述了这两个函数如何处理进程的休眠与唤醒,特别是在等待队列中的任务调度。通过对函数执行流程的分析,探讨了不同休眠状态下,进程如何响应信号以及唤醒机制的工作原理。

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,current和tmp,其中*p指向等待队列的头,也就是最近被放入等待队列的任务,current指向当前任务,tmp是在任务内核堆栈上建立的一个临时指针。在sleep的入口处,会让

       tmp = *p;

       *p= current;

这样的话tmp指向原来的头,*p指向新的头,这样就相当于串联起一个链表一样的结构,通过*p可以找到第一个等待任务,再通过第一个任务里面的tmp结构又可以找到下一个等待任务。下图可以帮助理解:

        

之后执行current->st

<think>根据用户需求,用户希望查找Linux 0.11版本中fork.csched.c文件的流程图。由于引用内容中提到了Linux 0.11内核的相关资料,特别是引用[1][3]涉及内核启动模块结构,但未直接提供流程图。因此,需要基于现有知识参考资料推断如何获取或创建流程图。 由于我无法直接生成图片,我将描述流程图的关键步骤,并建议用户参考相关博客或使用工具(如Graphviz)根据代码生成流程图。同时,可以引用提到的博客资源(如优快云博客)作为参考。 对于fork.c文件: - 主要功能:实现进程创建(fork系统调用)。 - 关键函数:`fork()`,它调用`copy_process`来复制父进程的数据结构。 - 流程图步骤可能包括: 1. 申请进程描述符(task_struct)。 2. 复制父进程的页表。 3. 设置子进程的寄存器状态(确保返回0)。 4. 将子进程加入就绪队列。 对于sched.c文件: - 主要功能:任务调度,包括进程调度时钟中断处理。 - 关键函数:`schedule()`,`sleep_on()`,`wake_up()`等。 - 流程图步骤可能包括: 1. 遍历进程队列寻找就绪态进程。 2. 进程切换(上下文切换)。 3. 处理等待队列(睡眠唤醒机制)。 由于引用[3]提到了内核模块结构中断机制,用户可参考该资料了解整体上下文。同时,引用[1]关于内核启动流程的笔记可能涉及sched.c中的初始化部分。 建议用户: 1. 阅读《Linux0.11内核完全注释》一书,其中可能有详细代码注释流程图。 2. 使用代码可视化工具生成流程图(如Doxygen或Graphviz)。 3. 参考优快云博客中的相关文章(如引用[1][3][4]提到的博客)。 最后,根据指令要求生成相关问题。 </think>### Linux 0.11 版本 fork.c sched.c 流程图解析 由于 Linux 0.11 是早期内核版本,其核心模块的流程图需基于源码逻辑构建。以下是两个文件的流程分析: #### **1. fork.c 流程图 (进程创建)** ```mermaid flowchart TD A[系统调用 fork] --> B[find_empty_process 获取空闲进程槽] B --> C{是否找到空闲槽?} C -->|是| D[copy_process 复制进程] C -->|否| E[返回 -EAGAIN 错误] D --> F[复制 task_struct 结构体] F --> G[复制页表内存数据] G --> H[设置子进程寄存器状态] H --> I[设置子进程返回值=0] I --> J[添加子进程到就绪队列] J --> K[返回子进程PID] ``` **关键步骤说明**: - `find_empty_process()` 在全局任务数组 `task[64]` 中寻找空位[^3] - `copy_process()` 执行核心复制操作: - 复制父进程代码/数据段(写时复制机制) - 设置子进程 `tss`(任务状态段)的 `eax=0` 实现 fork 返回值差异[^1] - 更新文件打开计数等资源引用 #### **2. sched.c 流程图 (进程调度)** ```mermaid flowchart LR A[时钟中断] --> B[schedule 调度器] B --> C{当前进程是否需要调度?} C -->|是| D[遍历任务链表 task[]] D --> E{找到下一个就绪态进程?} E -->|是| F[switch_to 上下文切换] E -->|否| G[执行 idle 空循环] F --> H[加载新进程 TSS 描述符] H --> I[更新 cr3 寄存器切换页表] I --> J[新进程开始执行] ``` **核心调度逻辑**: - 通过 `switch_to(next)` 宏实现上下文切换[^1] - 使用 `ljmp` 指令加载新进程的 TSS 选择子 - 调度策略为**轮转优先**:遍历所有进程,选择 `counter` 值最大的就绪进程[^3] - `sleep_on()` 函数实现进程阻塞队列(通过 `tmp->next` 链式结构)[^4] > 📌 **注意事项**: > 1. 完整流程图建议参考《Linux 0.11 内核完全注释》第 4 章 > 2. 实际源码中`sched.c`还包含定时器(`timer_interrupt`)信号处理 > 3. `fork.c` 涉及内存管理模块(`copy_mem`函数调用`get_free_page`)[^1][^3] --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值