(莱昂氏unix源代码分析导读-13)系统初启(6)

 #0进程的switch                  

我们已经了解了进程的switch原理,接下来,我们继续跟踪#0进程,看发生了什么。

 

1940: sched()

1941: {

……

1951: goto loop;

……

1957: loop:

1958:      spl6();                                                                                         /cpu priority设置为6

1959:      n = -1;

1960:      for(rp = &proc[0]; rp < &proc[NPROC]; rp++)                      /目前,仅有#0#1两个进程,且都

1961:      if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 &&     /SLOAD。故,if语句内不会被执行到

1962:             rp->p_time > n) {

1963:                  p1 = rp;

1964:                  n = rp->p_time;

1965:            }

1966:      if(n == -1) {                                                                                 /n-1

1967           runout++;                                   

1968           sleep(&runout, PSWP);                                                            /执行sleepPSWP=-128

1969           goto loop;

1970: }

1971 ……

 

066: sleep(chan, pri)

2067: {

2068:     register *rp, s;

2069:

2070:     s = PS->integ;

2071:     rp = u.u_procp;

2072:     if(pri >= 0) {                                                /调用时,pri = PSWP

                                                                                   /    <0,故跳过对if内对signal的处理

                 ……

2087:     } else {

2088:          spl6();

2089:          rp->p_wchan = chan;                            

2090:          rp->p_stat = SSLEEP;                          /#0进程状态改为SSLEEP

2091:          rp->p_pri = pri;          

2092:          spl0();

2093:          swtch();                                                 /调用swtch

2094:     }

2095:     PS->integ = s;

2096:     return;

2097:     ……

 

2178: swtch()

2179: {

2180:     static struct proc *p;

2181:     register i, n;

2182:     register struct proc *rp;

2183:

2184:     if(p == NULL)

2185:            p = &proc[0];

2186:     /*

2187:      * Remember stack of caller

2188:      */

2189:     savu(u.u_rsav);                                            /保存当前进程的spr5

2190:     /*

2191:      * Switch to scheduler's stack

2192:      */

2193:      retu(proc[0].p_addr);                                /切换到#0进程(当前进程就是#0进程,故此语句其实没有切换进程)

2194:

2195: loop:

2196:      runrun = 0;

2197:      rp = p;

2198:      p = NULL;

2199:      n = 128;

2200:      /*

2201:      * Search for highest-priority runnable process

2202:      */

2203:      i = NPROC;

2204:      do {                                                                                             /在进程表里寻找满足SRUN状态、

2205:         rp++;                                                                                        /flagSLOAD的进程,如有多

2206:         if(rp >= &proc[NPROC])                                                       /个,则选择优先级最高的那个

2207:               rp = &proc[0];                            

2208:         if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) {     /事实是,这样的进程只有1个,即

2209:               if(rp->p_pri < n) {                                                           /我们的#1号进程

2210:                  p = rp;

2211:                  n = rp->p_pri;

2212:               }

2213:         }

2214:      } while(--i);

2215:      /*

2216:       * If no process is runnable, idle.

2217:       */

2218:      if(p == NULL) {                                                                           /p指向#1进程,不为NULL

                           ……

2222:       }

2223:       rp = p;

2224:       curpri = n;

2225:       /* Switch to stack of the new process and set up

2226:       * his segmentation registers.

2227:       */

2228:       retu(rp->p_addr);                                                                         /切换到#1进程

2229:       sureg();                                                        

                      ……

2240:       if(rp->p_flag&SSWAP)                                                               /显然,if内表达式为false

2241:          rp->p_flag =& ~SSWAP;                                                          /不会被执行

2242:          aretu(u.u_ssav);

2243:       }

……/

2247:       return(1);                                                                                       /return !!                    

2248: }

 

问题出现了——我们并没有为#1进程调用过savu#1进程会return到哪里去呢?

让我们掉过头来仔细寻找,在newproc()中:

1826 newproc()

……

1889      savu(u.u_rsav);                                          /保存#0spr5(到#0进程的u中)

……

1914             while(n--)                                           /复制#0的私有空间的内容,赋给新进程

1915                  copyseg(a1++, a2++);                  /因此,此时#0spr5也被保存在#1u

 

return(1)将跳回newproc的调用者——main中去!

 

【思考题】:如果我们想切回#0进程,调用retu的参数应该是什么?

                        而程序调用后retu后,return语句会跳到哪里?

 

  博客地址:http://blog.csdn.net/cszhao1980

 博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 《莱昂UNIX源码分析》是一本经典的计算机技术书籍,全书共分为五个部分,详细介绍了UNIX操作系统源代码及其实现原理。该书以莱昂UNIX源代码为基础,通过源代码的解析和分析,深入探讨了UNIX操作系统的内核设计、进程管理、文件系统、网络通信等核心内容。 在《莱昂UNIX源码分析》中,作者通过逐行分析UNIX操作系统源代码,揭示了UNIX操作系统的内部工作机制。读者可以通过学习这本书,深入理解UNIX操作系统的运行原理,并且从中获得对操作系统设计和实现的深入洞察。 此外,该书还提供了大量的实例代码和实验,帮助读者动手实践和验证。通过实际的操作和实验,读者可以更好地理解和掌握UNIX操作系统的核心概念和原理。 《莱昂UNIX源码分析》可以说是UNIX操作系统研究者和操作系统开发者的必备参考书籍之一。通过阅读该书,读者可以系统地学习和掌握UNIX操作系统源代码和实现原理,为自己的研究和开发工作提供有效的指导和帮助。无论是对于对UNIX操作系统感兴趣的学生还是从事操作系统相关工作的专业人士,这本书都是必不可少的学习资料。 ### 回答2: 《莱昂UNIX源码分析》是一本非常经典的Unix操作系统源码分析书籍,由Peter H. Salus于1994年编写。该书主要讲解了UNIX操作系统的内核源码,通过深入分析UNIX的实现原理和设计思想,帮助读者理解UNIX操作系统的核心机制。 书中首先介绍了UNIX的历史和发展背景,包括UNIX的创始人Ken Thompson和Dennis Ritchie,以及UNIX与其他操作系统的区别与联系。接着,作者详细解析了UNIX系统的整体结构和组成部分,包括进程管理、文件系统、内存管理、设备驱动等。 在分析过程中,作者引用了大量的UNIX源码片段,并逐行详细解释了每个函数或数据结构的作用和实现原理。读者可以通过学习这些源码片段,深入了解UNIX操作系统的实现细节。同时,作者还提供了一些实践性的示例,通过自己手动修改和运行源码,加深对UNIX系统的理解。 《莱昂UNIX源码分析》以其通俗易懂的语言和深入浅出的分析方式,成为了许多计算机科学等相关领域的学生和研究人员的必备参考书。通过阅读该书,读者不仅可以掌握UNIX操作系统的内部工作原理,还能够培养良好的源码阅读和分析能力。 总之,作为一本经典的UNIX源码分析书籍,《莱昂UNIX源码分析》通过讲解UNIX操作系统的实现原理,帮助读者深入了解UNIX的核心机制和设计思想。无论是对于计算机科学专业的学生,还是对于对UNIX操作系统感兴趣的人士,该书都值得一读。 ### 回答3: 《莱昂UNIX源码分析》是一本经典的计算机图书,对UNIX操作系统源代码进行了详细的解析。该书通过分析UNIX操作系统内核的源代码,深入剖析了UNIX操作系统的设计思想、核心机制和关键模块的实现方式。 在《莱昂UNIX源码分析》中,作者结合了自己多年的研究和实践经验,将UNIX操作系统内核的代码逐行逐句地进行解读,包括进程管理、内存管理、文件系统、设备驱动等方面。读者可以通过学习这本书,了解UNIX操作系统内部的各个模块是如何协同工作的,以及它们之间的相互关系。 该书不仅介绍了UNIX操作系统的基本原理和设计思想,还对各个模块的实现细节进行了详细的讲解。通过对源代码的解析,读者可以了解到UNIX操作系统是如何管理进程、分配内存、访问文件、处理中断等一系列操作的。 《莱昂UNIX源码分析》以其深入浅出的语言和逻辑结构,引导读者逐步理解UNIX操作系统的设计和实现。读者可以通过学习这本书,提升自己的系统编程能力,加深对UNIX操作系统的理解。 总之,《莱昂UNIX源码分析》是一本非常值得阅读的图书,它对UNIX操作系统源代码进行了全面深入的分析,对于希望深入了解UNIX操作系统内部工作原理的读者来说,是一本非常好的参考书。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值