- 我是一个线程(修订版)
- 我是一个 Java class
- Javascript:一个屌丝的逆袭
- Java : 一个帝国的诞生
- JSP 一个装配工的没落
- TCP/IP 之 大明王朝邮差
- TCP/IP 之大明内阁
- TCP/IP 之蓟辽督师
- CPU 阿甘
- CPU 阿甘之烦恼
- CPU 阿甘:函数调用的秘密
- 我是一个网卡
- 我是一个路由器
- 我是一个进程
- 我是一块硬盘(上)
- 我是一块硬盘(下)
- 我是一个键盘
- 张大胖的 socket
- 张大胖学递归
- 学习面向对象的令狐冲
- 张大胖学数据库
- 数据库村的旺财和小强
- 小李的数据库之旅(上)
- 小李的数据库之旅(下)
- 漫画:什么是机器学习?
- 那些烦人的同步和互斥问题
- IE 为什么把火狐和 Chrome 给打伤了?
- 对浏览器村的第二次采访
- 节约标兵 IE 的自述
- EMail 诞生记
- Email 诞生记(下)
- Http 历险记(上)
- Http 历险记(下)-- Struts 的秘密
- 动物王国的面向对象
- 冯·诺伊曼计算机的诞生
- Http Server : 一个差生的逆袭
- 张大胖的加法器
- 从 1 加到 100:一道简单的数学题挑战下你的大脑
- 编程语言
- Javascript:一个屌丝的逆袭
- 计算机语言之战
- 我和编程语言的爱恨情仇(上)
- 我和编程语言的爱恨情仇(下)
- Android 为什么选择了 Java
- iOS 为什么选择了 Object-C?
- Basic : 一个老兵的自述
- Node.js : 我只需要一个店小二
- 命令式编程 vs 声明式编程
- 编译还是解释?
- 程序人生
- “架构师"小赵
- 师兄说
- 师姐说
- 小王的架构师之路
- 小李的版本管理系统
- 小超穿越记
- 小李的 Build 之路(上)
- 小李的 Build 之路(下)
- 张大胖改 Bug
- 我的编程之路--大学趣事
- 码农小王的一天
- 小李在外企
- 张大胖的需求估算
- 从厨师到码农
- 聊一聊那些神一样的程序员们(上)
- 聊一聊那些神一样的程序员们(中)
- 聊一聊那些神一样的程序员们(下)
- 谁是互联网之父?
- 一个价值百万的创业教训
- 让自己与众不同 - 提升工作的价值
- 看看你的“易燃性”
- 从无聊的工作中寻找价值
- 什么样的学生适合报考计算机?
- 谈谈程序员的职业方向(上)
- 谈谈程序员的职业方向(中)
- 谈谈程序员的职业方向(下)
- 谈谈培训班的作用
- 码农需要知道的“潜规则”
- 学习编程的加速度
- 码农在工作中的必备能力
- 码农和英语
- 老司机经验
- 假如时光能够倒流, 我会这么学习 Java
- 假如我是计算机系老师
- 学会编程, 而不是学会 Java
- 从增删改查中突围
- 抽象:程序员必备的能力
- 懒就一个字
- 编程的自学方法
- 小王买房记
- 从一道面试题谈谈一线码农应该具备的基本素质
- 想写框架的看过来
- 苹果手机变砖头以后
- 如何快速的学习一门技术?
- 唯一不变的是变化: 谈谈微信应用号
- 什么是企业应用?
- 勿以浮沙筑高台
- 为什么敏捷开发难于成功?
- localhost vs 127.0.0.1
- GitHub/Stackoverflow 找工作时有什么用?
- 动词 or 名词 :这是一个问题
- 如何选择入行语言
- 有时候,沉默是金
- 零 Bug 的代码是怎么炼成的?
- 浮点数为什么不精确?
- 文章错误大全
- Open Source--不要为了开源而开源
- 一不留神,代码就腐化了
- 先做个“键盘侠”, 再来写程序
- 不加断点调试的程序员是好程序员
- 码农必备技能:烂代码的处理之道(上)
- 码农必备技能:烂代码的处理之道(下)
- 学习数据结构有用吗?
- 从现在开始,丰富你的简历
- 那些永不过时的书,你看过几本吗?
- 学好编程必备的一个品质你知道吗?
- 你最爱的 Java
- 搞懂了这几点,你就学会了 Web 编程
- Spring 的本质系列(1) -- 依赖注入
- Spring 本质系列(2)-AOP
- 三层架构和 MVC 那点事儿
- Java 帝国之拨云见日识回调
- 小张的 Duck Typing
- JDBC 的诞生
- JDBC 后传
- 一个不安分的 JDBC 驱动
- Java 帝国之 Java bean (上)
- Java 帝国之 Java bean(下)
- Java 帝国之函数式编程
- Java 帝国之函数式编程(下)
- 关于 Java 初学者需要知道的 10 件事
- JUnit 你不知道的那些事儿
- 圣诞礼物:Java EE 的历史
- Java EE 读书指南
- 给小白的 Java EE 指南
- 给小白的 Java EE 指南(2)
- 给小白的 Java EE 生存指南(3) : XML
- 给小白的 Java EE 生存指南(4) : 一只叫 Tom 的猫
- 给小白的 Java EE 指南(5) : AJAX
- 给小白的 Java EE 生存指南(6) :Java 反射
- 闲聊
- "饿了么"初体验
- 来自大脑的控诉
- 一个高中生是怎么玩自媒体的?
- 尝试 分答
- 到底应不应该上培训班?
- 自学编程中遇到问题怎么办?
- 据说 99%的初级程序员看完后都不迷茫了
- 一行代码引发的“血案”
- 对一个死锁问题的思考
- 通过外包进入名企
- 请开往十年前的今天
- 为什么自学中最好有个师傅指导一下?
- 这个网站值得你花时间投入
- 为什么你无法坚持自学编程?
我是一个进程
我听说我的祖先们生活在专用计算机里, 一生只帮助人类做一件事情,比说微积分运算 了、人口统计了 、生成密码、甚至通过织布机印花 !
如果你想在这些专用“计算机”上干点别的事儿,例如安装个游戏玩玩, 那是绝对不可能的, 除非你把它拆掉, 然后建一个全新的机器。 而我这些祖先们勉强可以称为“程序”。
后来有个叫冯诺依曼的人, 非常了不起, 他提出了“存储程序”的思想, 并且把计算机分为五大部件: 运算器、控制器、存储器、输入设备、输出设备。
各种各样不同功能的程序写好以后,和程序使用的数据一起存放在计算机的存储器中,即“存储程序”;然后,计算机按照存储的程序逐条取出指令加以分析,并执行指令所规定的操作。
这样一来,原来的专用计算机变成了通用的计算机,不管你是计算导弹弹道的,模拟核爆炸的,还是计算个人所得税的, 统统都可以在一台机器上运行, 我就是其中的一员: 专门计算员工的薪水。
进程的诞生 我所在的计算机是个批处理系统, 每次上机时, 我和其他程序都排好队, 一个接一个的进入内存运行。
每个月末是发薪日, 我都要运行一次,这样我每月都能见一次 CPU 阿甘, 这个沉默寡言,但是跑的非常快的家伙。
我知道内存看阿甘不顺眼,还告了它一状,说他一遇到 IO 操作的时候,就歇着喝茶 ,从来不管不问内存和硬盘的忙的要死的惨境。
其实我倒是觉得挺好, 这时候正好和阿甘海阔天空的聊天,他阅程序无数, 知道很多内部消息,每一个字节都清清楚楚, 和他聊天实在是爽。
又到了月末发薪水的时候, 我刚一进入内存,便看到这么一个公告:
公告 为了创建和谐社会,促进效率和公平, 充分发挥每一个人的能力,经系统党委慎重研究决定:本系统自即日起,正式从“批处理系统”转为“多道程序系统”, 希望各部门通力配合,一起完成切换工作。 系统党委
xxxx 年 xx 月 xx 日
我正想着啥是多道程序系统, 阿甘便打电话给内存要我的指令开始运行了。
和之前一样,运行到了第 13869123 行,这是个 IO 指令, 我欢天喜地的准备和阿甘开聊了。
阿甘说: 哥们, 准备保存现场吧, 我要切换到另外一个程序来运行啦!
“啊 ? 我这正运行着呢! 咱们不喝茶了?
“喝啥茶啊,马上另外一个程序就来了!”
" 那我什么时候回来再见你?” 我问道。
“等这个 IO 指令完成,然后操作系统老大会再给你机会运行的。”
“那谁来记住我当前正在运行第 13869123 行? 还有刚把两个数据从内存装载到了你的寄存器,就是那个 EAX, EBX , 你一切换岂不都丢了? ” 我有点着急。
阿甘说:“所以要暂时保存起来啊, 不仅仅是这些,还有你的那些函数在调用过程中形成的栈帧和栈顶, 我这里用寄存器 EBP 和 ESP 维护着, 都得保存起来。”
“还有” 阿甘接着说,“你打开的文件句柄,你的程序段和数据段的地址, 你已经使用 CPU 的时间,等待 CPU 的时间。。。。。。 以及其他好多好多的东西,统统都要保存下来。”
我瞪大了眼睛: “这也太麻烦了吧, 原来我只需要关心我的指令和数据, 现在还得整这么多稀奇古怪的东西”
“没办法,这就叫做上下文切换, 把你的工作现场保存好,这样下一次运行的时候才能恢复啊。 对了,老大给你们统一起了一个新的名称: 进程 ! 刚才那些需要保存的东西叫做叫做 进程控制块 (Processing Control Block, PCB ),”
我想了想,这个名字还挺贴切的, 一个真正进行的程序! 只是这个正在进行的程序随时可以被打断啊。
我只好保存好上下文,撤出 CPU, 回到内存里歇着去了,与此同时另外一个程序开始占据 CPU 运行。
其实我这个程序,奥,不对,我这个进程被放到一个阻塞队列里,等到 IO 的数据来了以后,又被赶到了就绪队列中, 最后才有机会再次运行,再次见到 CPU 阿甘。
阿甘从我的 PCB 中取出各种保存的信息,恢复了运行时现场, 可是忙活了好一阵, 没办法,这就是程序切换必须要付出的代价。
我有点同情阿甘了, 从此以后,他很难再悠闲和和我们海阔天空,每时每刻都处于高速的奔跑中。
得益于阿甘的高速度, 虽然在同一时刻只有一个程序在运行, 但是有很多程序在短时间内不断的切换, 在外界看来, 似乎多个程序在同时执行。
尤其是那些速度超慢的人类, 他们开着电脑一边听歌,一边上网,一边 QQ, 很是自在, 理所当然的认为这些程序就是同时在运行。 岂不知阿甘是让音乐播放器上运行几十毫秒, 然后打断,让浏览器进程运行几十毫秒,再打断,让 QQ 也运行几十毫秒,如此循环往复。
唉,阿甘真是能者多劳啊, 这个计算机系统也算是达到了我们党委的目标:兼顾了效率和公平。 线程 有了进程就万事大吉了吗? 人类的欲望是无止境的,很快就出现了新情况, 举个例子来说吧,我有一个兄弟,是个文字处理软件, 他和我不一样, 他有界面, 人类在用的时候能看到, 这实在是很幸福, 不像我总是在背后默默工作,几乎无人知晓。
这哥们有个智能的小功能,就是在人类编辑文档的时候能自动保存, 防止辛辛苦苦敲的文字由于断电什么的丢掉。
可是这个功能导致了人类的抱怨, 原因很简单,自动保存文字是和 IO 打交道,那硬盘有多慢你也知道, 这个时候整个进程就被挂起了, 给人类的感觉就是: 程序死了,键盘和鼠标不响应了! 无法继续输入文字, 但是过一会儿就好了。
并且这种假死一会儿就会出现一次(每当自动保存的时候), 让人不胜其烦。
系统党委研究了很久, 他们当然可以用两个进程来解决问题, 一个进程负责和用户交互, 另外一个进程负责自动保存, 但是,这两个进程之间完全是独立的,每个人都有自己的一亩三分地(地址空间), 完全互不知晓, 进程之间通信的开销实在是太大, 他们没有办法高效的操作那同一份文档数据。 后来还是劳模阿甘想出了一招 : 可以采用多进程的伟大思想啊!
把一个进程当成一个资源的容器, 让里边运行几个轻量级的进程, 就叫 线程 吧, 这些线程共享进程的所有资源, 例如地址空间,全局变量,文件资源等等。
但是每个线程也有自己独特的部分, 那就是要记住自己运行到哪一行指令了, 有自己的函数调用堆栈,自己的状态等等, 总而言之,就是为了能像切换进程那样切换线程。
问题基本解决了,但也带来了新的问题,我们的系统也变的越来越复杂, 尤其是进程之间的通信和线程之间的同步, 会那些程序员们带来无穷无尽的烦恼, 这是后话了, 有机会下次再说吧。
注: 本文的插图来源于《现代操作系统》和《操作系统概念》(恐龙书)这两本书, 我重画了一下。 对操作系统感兴趣的同学可以看看这两本书。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论