亲宝软件园·资讯

展开

操作系统-小结

山丘i 人气:1
**The mind is not a vessel that needs filling , but wood that needs igniting !** ### 1. 运转CPU 程序计数器pc 将pc置一个初值,然后取值执行,cpu就运转起来了 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210052416-23956622.png) ### 2. CPU没有好好运转 当遇到IO设备的时候,cpu得等待 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210109097-565508254.png) ### 3. 得让CPU好好运转 当程序1执行到一个程序需要等着别的程序执行,那么就先切到别的程序执行 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210125304-127667342.png) 怎么切换,不就是pc的跳转,利用栈来做 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210219582-1608219473.png) 当只有一个栈的时候问题就出现了, Yield:其作用是当前线程“放弃”执行,让操作系统调度另一线程继续执行 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210235929-676270266.png) **所以就出现了两个栈+两个用户TCB(线程控制块)** ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210242952-1810016216.png) ### 4. 一直在用户态那怎么行? 当前的再怎么切都是在用户切,根本进入不了内核 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210301189-1032051894.png) 引入了内核栈的切换 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210312311-779738246.png) ### 5. 实现这个idea 在屏幕上交替的打出A和B ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210331879-338086146.png) **从用户代码开始:** ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210344476-171871467.png) **fork是怎么工作的?** 1. 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 2. 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。 **fork函数的特性?** fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值 1. 在父进程中,fork返回新创建子进程的进程ID; 2. 在子进程中,fork返回0; 3. 如果出现错误,fork返回一个负值; 在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210418961-24156617.png) INT就进入了内核 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210429569-140182629.png) 然后就是执行system_call , 接下来就是sys_fork ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210435350-1361667358.png) 接着开始copy_process ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210445886-62953017.png) 然后就开始返回 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210455453-706675361.png) 现在是创建好了一个打印A的进程,现在需要返回创建一个打B的进程 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210502548-1944896372.png) 和上面类似,只是对应的tss->eip不同 然后父进程开始等待,也就是阻塞,然后调用schedule 总的来说:就是有一个进程,产生出两个打印A和打印B的子进程,对应着打印A和打印B的函数,然后父进程阻塞调用schedule,schedule就开始选择其中的一个进程(根据选择算法),这里也就是打印A的进程,选择完了就切换过去, ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210519866-1592137328.png) ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210524014-1842060925.png) 也就是把当前cpu中的信息拍到当前父进程中,然后把A的PCB中的tss扣到cpu上 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210533656-1929071697.png) 这就切换过去了,而cpu一直就是取指执行,此时eip=100,而eax=0,接下来程序中A就开始不断的执行 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210541756-287440560.png) ### 6. 怎么打出B 前面是进程A开始不断的打A了,而该怎么交替的打印A和B? 要想打印B,那么必须需要B这个进程执行,也就是得切换B进程对应的PCB,而切换的程序和上面的一样,schedule、switch_to,那么现在需要一个调用,也就是调用到schedule的入口,这个就是**调度点**,由于是交替打印A和B,那么这个调度点该放到什么位置合适呢? **需要中断,时钟中断** ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210604107-800539271.png) 也就是对于A来说,先执行一会,当前的counter=0就调用schedule,和上面一样,也是通过switch_to,把对应的数据进行交换,然后B执行 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210613779-1921123879.png) ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210617084-805629174.png) 何为交替?还是中断,因为时钟中断已经做好了,每过一段时间就要做一次时钟中断 ![](https://img2020.cnblogs.com/blog/1212924/202003/1212924-20200311210625585-723114184.png) 这个时候A和B就交替的出现了

加载全部内容

相关教程
猜你喜欢
用户评论