⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000002.htm

📁 一份很好的linux入门资料
💻 HTM
📖 第 1 页 / 共 3 页
字号:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.将栈顶寄存器压入堆栈.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.调用&nbsp;StartupPC&nbsp;函数.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.调用&nbsp;InitialPC&nbsp;&nbsp;函数.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.调用&nbsp;WhenDonePC&nbsp;函数.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.恢复栈顶寄存器.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;事实上执行&nbsp;WhenDonePC函数过程中,此进程就放弃了处理机,由其他进程将它所占&nbsp;<BR>的内存空间释放,此进程将不再运行.从ThreadRoot函数的执行过程可以看出它才是进&nbsp;<BR>程运行的全过程.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;正文切换中用到的另一个函数是SWITCH(Thread*&nbsp;oldThread,Thread*newThread),&nbsp;<BR>oldThread指向正在运行的进程对象,newThread指向将要运行的进程对象,在Thread对&nbsp;<BR>象中有一块内存用来放本进程的CPU寄存器的内容,SWITCH函数先将宿主机的CPU寄存器&nbsp;<BR>的内容保存到oldThread对象中,再从newThread对象中恢复除指令寄存器(PC)以外的所&nbsp;<BR>有寄存器的内容,由于栈基址和栈顶寄存器的内容变为新进程的值,所以程序将在新进&nbsp;<BR>程的堆栈上运行,当SWITCH函数结束返回时,会从新进程的堆栈中取出返回地址,这个地&nbsp;<BR>址是新进程的断点而不是老进程的断点,所以CPU将执行新进程的代码,由此实现新老进&nbsp;<BR>程的正文切换.因为SWITCH需要存取CPU寄存器,并且与具体机器有关,所以它用汇编语&nbsp;<BR>言写成.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Scheduler类用于实现进程的调度.它的类界面如图所示:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┏━━━━━━━━━━━┓&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;&nbsp;&nbsp;&nbsp;Scheduler&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┣━━━━━━━━━━━┫&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;&nbsp;&nbsp;ReadyToRun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;&nbsp;&nbsp;FindNextToRun&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;&nbsp;&nbsp;Run&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┗━━━━━━━━━━━┛&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Schedule类维护一个就绪进程队列,当一个进程可以占用处理机时,就可以调用&nbsp;<BR>ReadyToRun成员函数把这个进程放入就绪进程队列,并把进程状态改成就绪态.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;FindNextToRun函数根据调度策略,取出下一个应运行的进程,并把这个进程从就绪&nbsp;<BR>进程队列中删除.如果就绪进程队列为空,则此函数返回空(NULL).现有的调度策略是先&nbsp;<BR>进先出策略(FIFO),在课程中将要求学生们实现其他的调度策略.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Run函数用来调用另一个进程占用CPU.它的实现过程是:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.如果当前进程(由currentThread指明)是用户进程,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;则保存用户程序状态和用户空间的状态.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.将新进程的地址赋给currentThread变量,表明当前进程变为新进程了.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.将新进程的状态改为运行态.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.调用SWITCH函数切换进程正文.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.查看有没有已经结束但没有删除的进程,如果有,则将其删除.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6.如果新进程是用户进程,则恢复用户程序状态和用户空间的状态.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;当老进程是因为结束而放弃CPU,我们要把它所占的内存释放,那么在什么时候删除&nbsp;<BR>它呢?这里有个时机问题.我们只能在第五步上删除,在此之前是不行的.因为在此之前,&nbsp;<BR>程序还运行在老进程的堆栈上,如果过早删除老进程,它的堆栈也被删掉了.造成内存出&nbsp;<BR>错.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Thread类的对象既用作进程的控制块,保存进程状态和CPU寄存器内容,又是用户调&nbsp;<BR>用进程系统的界面.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;用户生成一个新进程的方法是:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;生成一个进程类*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Thread*&nbsp;newThread&nbsp;=&nbsp;new&nbsp;Thread(&quot;New&nbsp;Thread&quot;);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;/*定义新进程的执行函数及其参数*/&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;newThread-&gt;Fork(ThreadFunc,ThreadFuncArg);&nbsp;<BR>&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Fork函数分配一块固定大小的内存作为进程的堆栈,在栈顶放入ThreadRoot的地&nbsp;<BR>址.当新进程被调上CPU时,要用SWITCH函数切换进程图像,SWITCH函数返回时,会从栈&nbsp;<BR>顶取出返回地址,所以将ThreadRoot放在栈顶,SWITCH结束后就会执行ThreadRoot函数&nbsp;<BR>了.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;ThreadRoot函数在前面已作了介绍,它是进程完整的执行过程.它的InitialPC及&nbsp;<BR>InitialArg参数传的是Fork的两个参数;StartupPC参数传的是一个开中断函数,它将&nbsp;<BR>在进程首次占用处理机时立即执行;WhenDonePC参数传的是Thread类的Finish成员函&nbsp;<BR>数,它将在进程的工作函数执行完毕后运行,作一些收尾工作.它的执行过程是:&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.关闭中断.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.将当前进程赋给全局变量threadToBeDestroyed,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以便在它让出CPU后,在SWITCH函数中将它删除.&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.调用Sleep函数睡眠等待.实际上进程在睡眠等待的时候就被删除了,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所以它不会从Sleep函数中返回的.&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Yield函数用于本进程放弃处理机.它的执行过程是:&nbsp;<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┏━━━━━━━━┓&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;关闭中断并记住&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;原来的中断状态&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┗━━━┳━━━━┛&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;↓&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;━━━━━━━━━&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Y&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;进程就绪队列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;━━━┓&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;为空?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;━━━━━━━━━&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃N&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃&nbsp;<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -