.1 程序间的聊天
我们这些执行 程序都安安静静地躺在 硬盘的某个角落中,满心期待地等待被主人使用,被操作系统装载,然后进入内存工作,确
切地说:被 CPU阿甘执行。进入内存是我们的使命,如果只是在硬盘上呆着,那我们就是一堆二进制的代码而已,除了占用硬盘的空间,没有什么作用。
但是主人似乎特别钟情于其中的几个程序,像什么浏览器、 QQ、Word、 播放器, 80%以上的时间都耗在他们上面执行。像我这样的小工具calculator,默默无闻也无人问津, 除了躺在硬盘里睡大觉,就是和同一目录下的helloworld聊天。helloworld也很悲催,自从主人把它创建出来,只运行过一次,在屏幕上输出一个 hello world !以后就再也没人搭理了。可是我更悲催, 连一次运行的机会都没有,我曾经好奇地问helloworld ,在内存中执行到底是什么感觉,这个糊涂蛋竟然说:“木有感觉,代码很快就运行完了,我这个程序就退出了”。我又去找同一目录下的game老兄, 他多次进入内存运行,见多识广。
“我自己是一名从事了10年的老程序员,辞职目前在做讲师,今年年初我花了一个月整理了一份最适合2018年学习的c++干货,从最基础的到深入的都有整理,送给每一位编程小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。"
加QQ群:953788065(招募中)
本人从事c++在线教育十年工作经验现在精心整理了一套从小白到项目实践开发各种学习资料如果你想学想加入我们请关注我私信“编程”可以领取学习资料!!!记住一定要私信才有
没想到game愤愤然地说: “我告诉你啊,你要想进入内存执行,必须得通过操作系统来装载,但是操作系统他就是个大骗子!”。
calculator问“为什么啊?”。 game老兄回答说:
• “第一,他和CPU阿甘狼狈为奸,营造了一个假象,让我们以为每个程序都可以使用3GB的巨大内存空间,但实际上那只是
虚拟的!我们使用的内存实际上少得可怜!”
• “第二,他不是把你这个程序一下子全部装入物理内存,而是把你大卸八块,用他的术语讲,叫做页面(page) ,然后分页按需
装入内存, 注意,他不是连续装入的,有时候先装入这一块,有时候先装入那一块, 最后你都不知道自己身体的各个部位在内存
的什么地方,绝对是痛不欲生。 ”
• “第三,你以为在运行时独占CPU,别做梦了,操作系统通过分配时间片的方式,让我们这些程序,不,准确的来讲是 进程来轮
转执行,再加上一点进程调度的算法, 时不时地把你踢出CPU。由于各个进程切换得非常快,给人类形成了一个假象,好像各个
程序在同时执行一样。你说他是不是个大骗子? ”
• 2 程序装载
伟大的一天终于来临了。主人在命令行窗口敲入了 calculator,正在磁盘睡大觉的我立刻被装载器(loader)唤醒,他说他是操作系统派来的, 要帮我到内存去执行。我满心欢喜,等待装载器把我装入内存,可是等了半天,什么也没有发生, 我不由得问他:哥们,难道不是让我进入内存运行吗?装载器说: “急什么,看你那没见过世面的样子,不知道我正在
为你在系统登记信息和创建虚拟地址空间吗? ”。果然如此 !要给我建立一个虚拟的空间了 ,好吧,既来之则安之。“你是不是忙着把我的代码和数据都复制到这个虚拟地址空间中来啊?” 我故意问道。“真够无知的,这是虚拟地址空间,不是实际内存,怎么可能放代码和数据?” 这个装载器脾气很大。我以为这个装载器至少会把我的代码装载到物理内存,然后在虚拟内存和物理内存直接建立映射。于是耐心等待。但是这个装载器却并没有这么做, 实际上他除了读取我的一些Header信息之外,根本没有把我的数据Copy到物理内存去,他到底要做什么?我质问道:“你不把我的代码装载到物理内存中,我怎么运行? ”他说: “放心吧,我已经用一个数据结构 (页表)把你的代码/数据在硬盘的位置已经记录下来了,等到真正运行的时候会被装载的。” 说着他甩给我一张图: “看到了页表了吗,绿色的表示已经装入内存, 黄色的表示还在磁盘上, 初始状态下,全是黄色的,就像你一样。”这个大脾气的装载器把活干完了 ,大大咧咧地从我的代码中找到了程序的入口点地址(假设是0x080480c0),他说等到进 进程执行的时候就从这里开始,读取第一条指令。
•3 程序运行
我意识到自己虽然还躺在硬盘里, 但是 操作系统老大已经为我建立了一个 进程了,这个进程有一套自己的虚拟地址、一个
进程控制块、页表等“高级”的数据结构,可以准备运行了。果然, 不久以后, 操作系统调度了我这个进程来运行,就从装载器返回的程序入口点0x080480c0开始。老大命令CPU阿甘去0x080480c0处取出指令来执行, 但这是一个虚拟地址,必须转化成物理地址才行。于是阿甘就去查看页表,试图把它变成物理内存的地址, 可是这个页表指向的是硬盘中的地址, CPU阿甘立刻报告:“老大,这是个新家伙,它的代码还在硬盘上呢!”“好的,马上启动缺页异常处理程序! ” 看来老大已经司空见惯了。缺页异常处理程序开始执行, 根据页表中的地址又在硬盘中找到了我, 我配合着让他把代码取走。人生的第一次, 我的代码终于被读入了内存当中,当然,阿甘也得把页表给修改一下,这样才能反映已经数据已经进入内存了。现在可以读取虚拟地址0x080480c0处的内容了, 通过页表的翻译,定位到了物理内存的地址,取出了指令,终于可以执行了 !随着指令的执行,越来越多的数据和代码被装载到物理内存,果然如game所言,我被大卸八块安插到物理内存的不同位置去了。但是game老兄说的也不对,那其实并不是我,只是我的一个化身而已。 这个化身是一个正在运行的进程,CPU阿甘不停地读数据、写数据。 时间片到了,就把这个进程给挂起,过一会儿再运行。最后,进程结束,内存中的数据会被清理、覆盖,但是我还是我,玩好无损地躺在硬盘上。经历了这一次的运行,我算是明白了,操作系统确实是个大骗子,但是他其实也很不容易,资源很有限,内存就那么大,CPU阿甘只有一个,程序又那么多,为了让更多的程序运行,更有效地利用内存和CPU, 也只能施展一点骗术了。
“我自己是一名从事了10年的老程序员,辞职目前在做讲师,今年年初我花了一个月整理了一份最适合2018年学习的c++干货,从最基础的到深入的都有整理,送给每一位编程小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。"
加QQ群:953788065(招募中)
网友评论