当前位置: 首页 > news >正文

北京做网站推广兼职aspcms建站

北京做网站推广兼职,aspcms建站,做网站为什么能赚钱,不忘初心 继续前进网站怎么做首发公号#xff1a;Rand_cs 本文讲述 xv6 中的一些细节流程#xff0c;还有对之前文中遗留的问题做一些补充说明#xff0c;主要有以下几个问题#xff1a; 一次完整的磁盘中断流程进入调度器后的详细流程sched 函数中的条件判断scheduler 函数中为什么要周期性关中断 …首发公号Rand_cs 本文讲述 xv6 中的一些细节流程还有对之前文中遗留的问题做一些补充说明主要有以下几个问题 一次完整的磁盘中断流程进入调度器后的详细流程sched 函数中的条件判断scheduler 函数中为什么要周期性关中断 一次完整的磁盘流程 此节讲述完整的磁盘读写流程读写的流程总体差不多这里以读为例子先看“流程图”看代码时的笔记图 readint $T_SYSCALLsys_readfilereadreadibreadbgetiderwidestart还是从 A 进程的用户态 read 函数开始 A 进程用户态调用 read 读取磁盘上的数据read 通过 INT 0x80 软件中断通过中断门进入内核此时会关中断NOTE 这里我以中断门来实现系统调用为例会关中断xv6 源代码是以陷阱门实现系统调用不会关中断期间多次取锁放锁进行了多次 pushcli 和 popcli但总是成对存在所以目前总体还是处于 0 次 puchcli 状态如果磁盘数据没有缓存调用 iderw 来读写磁盘 A 进程内核态iderw 函数 acquire(idelock)获取磁盘锁pushclicpu.IF 01 次pushcli 状态调用 idestart将要读写的命令扇区号等信息写进磁盘端口以此来请求磁盘操作。写磁盘端口是通过 out 指令实现的。向磁盘发送命令后磁盘就会工作磁盘完成工作后就会向 cpu 发送中断信号。A 进程调用 sleep 等待磁盘操作完成。在 sleep 函数中获取 ptable.lock释放 idelock然后调用 sched 让出 by the way这里补充说明 sched 函数中的条件检查之前的文章都一笔带过了 void sched(void) //让出CPU重新调度 {int intena;struct proc *p myproc();if(!holding(ptable.lock)) // 必须持有 ptable.lockpanic(sched ptable.lock);if(mycpu()-ncli ! 1) // 1 次 pushcli 状态panic(sched locks);if(p-state RUNNING) // 只可能是 SLEEPING、RUNNABLE、ZOMBIE 三种状态之一panic(sched running);if(readeflags()FL_IF) // 此时肯定处于关中断状态(通过中断门进入内核会关中断1次pushcli状态也应该对应关中断状态)panic(sched interruptible);intena mycpu()-intena;swtch(p-context, mycpu()-scheduler);mycpu()-intena intena; }sched 函数中有 4 个条件检查 xv6 是个多 CPU 多任务系统在 sched 任务调度的时候需要持有 ptable.lock不然进程的上下文会发生紊乱举个简单的例子A 时间片到了先将 A 的状态设置为 RUNNABLE然后调用 sched 让出 CPU如果此时没有持有 ptable.lock那么 A 进程便可能在另一个 CPU 上被调度那么便出现一个进程在两 CPU 上运行的情况Error在 sched 函数中应当只有 1 次 pushcli 状态这个条件检查感觉有点难以理解。从实践看代码确实不管从哪条路径到达 sched 函数都应该只有 1 次 pushcli这是获取 ptable.lock 的锁造成的。从个人理解上说sched 是为了调度进程是要从 A 进程到 B 进程那么 A 进程的开关中断(pushcli popcli 次数)不应该带入 B 进程除了一种情况——调度那就是 A 进程获取 ptable.lock 但是要在 B 进程中释放 ptable.lock。所以 sched 中应当只有 1 次 pushcli在真正切换进程上下文之前会首先修改旧进程的状态在 xv6 中是 SLEEPING、RUNNABLE、ZOMBIE 三种之一在 sched 中理应处于关中断状态如果是通过中断门进入内核的那么本身就处于关中断。如果是通过陷阱门进入内核那么有 1 次 pushcli也会处于关中断状态 回到磁盘中断当 A 进程调用 sched 切换到 B 进程这里假如 B 进程最初是因为时间片到了调用 yield-sched-swtch 主动让出 CPU 的则 B 进程的流程如下 回到 B 进程 sched 函数中的 swtch 下一条指令处然后释放 ptable.lock此时 cpu.IF 00 次 pushcli 状态cpu.IF 0 仍然处于关中断状态 是因为 A 进程通过中断门进入内核关中断造成的B 进程经过一些列指令后最后执行 iret 返回 B 进程的用户态此时会开中断NOTE这里我们假设 CPU 内部逻辑每条指令执行后都会检查是否有中断发生如果有中断发生且开中断的情况下则去处理中断。再假设此前的磁盘操作已完成已经向 CPU 发生了中断信号。但是在此之前 CPU 一直没有去处理中断是因为在此之前一直处于关中断状态。NowCPU 处于开中断状态继续执行 B 进程的指令开中断后的第一条指令执行完成后检查是否有中断发生发现有磁盘中断那么中断 B 进程通过中断门进入内核(该过程关中断)执行磁盘中断处理程序也就是执行 insl 指令从 0x1f0 端口将磁盘数据读取到内存然后唤醒等待该磁盘事件的进程在我们的例子当中就是 A 进程中断执行完成iret 返回 B 进程用户态(该过程开中断)继续执行 B 进程的指令时钟中断 B 进程再次通过中断门进入内核(关中断)发现 B 进程的时间片到了那么调用 yield-sched-swtch 重新调度进程这里假设调度到 A 进程 回到 A 进程的内核态准确来说回到 iderw-sleep-sched-swtch 的下一条指令 A 进程执行 release(ptable.lock)、acquire(idelock)、release(idelock)此时状态 cpu.IF 00 次 pushcli将磁盘中断获取的数据 cp 到 A 进程内核态A 进程层层返回最后 iret 返回 A 进程用户态(开中断) 系统启动进入调度器后的流程 mainuserinit //准备好 initcode 进程mpmainscheduler // 进入调度器调度器上下文 第一次进入 schedulerfor 循环找到 RUNNABLE 进程目前就只有一个 initcode 进程为 RUNNABLE 进程找到并切换上下文到 initcode 进程 initcode 进程上下文 执行 forkret 函数因为是第一次执行会首先执行 iinit 来初始化根文件系统执行 readsb 从磁盘中读取超级块数据期间会使用 iderw 读写磁盘具体流程见第一小节。总之initcode 进程会调用 sleep 函数让出 CPU 来等待磁盘操作在 sleep-sched-swtch 中再次切换上下文到 调度器上下文 调度器上下文 切换到内核页表然后遍历任务队列寻找 RUNNABLE 进程但是目前只有一个且处于 SLEEPING 状态的进程所以这里调度器会轮询空转直到磁盘中断处理完成initcode 进程被唤醒。再次切换上下文到 initcode 进程 initcode 进程上下文 回到 forkret-iinit-readsb-bread-iderw-sleep-sched-swtch 的下一条指令处然后层层返回到 forkret再执行 initlog 恢复日志这里会涉及到两次磁盘读写道理同上不再赘述第 4 次调度到 initcode 进程后forkret 函数执行完毕再执行 trapret 函数其中包含了 iret 指令至此回到用户态开始执行 initcode 进程的逻辑 by the way again这里解释为什么在 scheduler 函数中需要周期性的开中断 void scheduler(void) {for(;;){sti(); // 周期性开中断for(p ptable.proc; p ptable.proc[NPROC]; p){ //循环找一个RUNNABLE进程...}} }进入调度器上下文有两条路径 系统刚启动进入 schedulersched 函数中 swtch 上下文到调度器 回想前面说的 sched 函数在它切换到新进程并返回用户态之前理应都处于关中断的状态。而一直处于关中断且没有开中断的话会引发死循环。 举个例子假设没有周期性的开中断也就是 scheduler 代码长这样的话 void scheduler(void) {for(;;){// 遍历进程列表寻找 RUNNABLE 进程for(p ptable.proc; p ptable.proc[NPROC]; p){...}} }假如当前系统只有一个进程shell进程它需要等待键盘输入而被阻塞(stateSLEEPING)内层循环是找不到 RUNNABLE 进程的便回到外层循环外层循环现在相当于什么也不做便又再次进入内层循环。如此下来死循环。 而加入周期性的开中断后CPU 便会响应中断。当有键盘输入时中断当前的调度上下文而进入中断上下文执行键盘中断处理程序唤醒 shell 进程中断处理完成后再回到调度上下文。此时内层循环便能找到一个 RUNNABLE 进程然后切换到它的上下文执行。 本文就先补充这么多吧这补充系列的文章是之前做了关于 xv6、nemu 的项目将 xv6 启动到 nemu 上这需要对很多地方细扣对 xv6 的理解又增加了一些分享出来。 停更这么久啊一直再忙工作学习新的东西时间不是很多当然也有懒的原因后面慢慢克服回归吧。OK那有什么问题欢迎来讨论交流。 首发公号Rand_cs
http://www.tj-hxxt.cn/news/227906.html

相关文章:

  • 企业网站建设专业去招聘网站做顾问
  • 网站管理员工作总结上海网站推广网络公司
  • 太原西北建设有限公司网站大连市建设部网站官网
  • 网站建设使用的什么软件有哪些甘肃省酒泉市做网站公司
  • 江门网站制作策划工程建设合同模板
  • 手机怎样建立网站一个网站每年维护费用
  • 矢量网站动画怎么做软件接口设计文档
  • 网站后台管理系统wordpress分类页首页调用分类描述
  • 个人网站开发与实现开题报告快速网站轻松排名
  • 永久打开本网站的音乐网站建设价格6
  • 吉林省 网站建设手机便宜网站建设
  • 哪些网站可以做网店常州市城乡建设学院网站
  • 人事处网站开发文献综述河南营销网站建设联系方式
  • 凤山县住房和城乡建设局网站17做网店这个网站做起多少钱
  • 网站名称注意事项注册域名邮箱
  • 网站月流量什么意思南宁网站建设培训
  • 挖矿网站开发南充响应式网站建设
  • 八年级微机网站怎么做网站开发后端有哪些
  • 做PPT素材图片网站 知乎购物网页模板
  • 专业模板建站软件外贸如何网络推广
  • 今鼎网站建设国外手机模板网站推荐
  • 住房和城乡建设部网站证书查询四平网站公司
  • 网站怎么做分享链接地址设计案例分享网站
  • 文字壁纸做背景处理的网站河间米各庄网站建设制作
  • 怎么用flash做网站江西智能网站建设哪家好
  • html 网站首页网站版面
  • 国外做调灵风暴的网站网站存在的问题及改进措施
  • 西安市建设局官方网站jinsom wordpress
  • 网上网站代码可以下载吗手机百度免费下载
  • 网站访问者qq黄骅做网站的电话