你可以把Linux内核当成一家软件外包公司的老板

电脑组装好就能直接用吗?


那时候买电脑,经常是这样一个情景:三五个哥们儿一起来到电脑城,呼啦呼啦采购了一大堆硬件,

  • 有密密麻麻都是针脚的 CPU
  • 有铺满各种复杂电路的一块板子,也就是主板
  • 还需要买块显卡,用来连接显示器
  • 还需要买个网卡,里面可以插网线
  • 还要买块硬盘,将来用来存放文件
  • 然后还需要一大堆线,将这些设备和主板连接起来
  • 最终再来一个鼠标,一个键盘,还有一个显示器。设备差不多啦,准备开整!

操作系统其实就像一个软件外包公司,其内核就相当于这家外包公司的老板。

在操作系统中,也有同样的问题,例如多个进程都要往打印机上打印文件,如果随便乱打印进程,就会出现同样一张纸,第一行是 A 进程输出的文字,第二行是 B 进程输出的文字,全乱套了。所以,打印机的直接操作是放在操作系统内核里面的,进程不能随便操作。但是操作系统也提供一个办事大厅,也就是系统调用(System Call)。

系统调用也能列出来提供哪些接口可以调用,进程有需要的时候就可以去调用。这其中,立项是办事大厅提供的关键服务之一。同样,任何一个程序要想运行起来,就需要调用系统调用,创建进程。 

在操作系统中,进程的执行也需要分配 CPU 进行执行,也就是按照程序里面的二进制代码一行一行地执行。于是,为了管理进程,我们还需要一个进程管理子系统(Process Management Subsystem)。如果运行的进程很多,则一个 CPU 会并发运行多个进程,也就需要 CPU 的调度能力了。

在操作系统中,不同的进程有不同的内存空间,但是整个电脑内存就这么点儿,所以需要统一的管理和分配,这就需要内存管理子系统(Memory Management Subsystem)。 

 

不过,无论是别人写的程序,还是你写的程序,运行起来都是进程。如果你是一家外包公司,一个项目的运行要使用公司的服务,那就应该去办事大厅,也就是说,你写的程序应该使用系统调用。 

 

立项服务与进程管理


首先,我们得有个项目,那就要有立项服务。对应到 Linux 操作系统中就是创建进程。

创建进程的系统调用叫fork。这个名字很奇怪,中文叫“分支”。为啥启动一个新进程叫“分支”呢?

在 Linux 里,要创建一个新的进程,需要一个老的进程调用 fork 来实现,其中老的进程叫作父进程(Parent Process),新的进程叫作子进程(Child Process)。

前面我们说过,一个进程的运行是要有一个程序的,就像一个项目的执行,要有一个项目执行计划书。本来老的项目,按照项目计划书按部就班地来,项目执行到一半,突然接到命令,说是要新启动一个项目,这个时候应该怎么办呢?

一个项目的执行是很复杂的,需要涉及公司各个部门的工作,比如说,项目管理部门需要给这个项目组开好 Jira 和 Wiki,会议室管理部要为这个项目分配会议室等等。

所以,我们现在有两种方式,一种是列一个清单,清单里面写明每个新项目组都要开哪些账号。但是,这样每次有项目,都要重新配置一遍新的 Jira、Wiki,复杂得很。另一种方式就是咱们程序员常用的方式,CTRL/C + CTRL/V。也就是说,如果想为新项目建立一套 Jira,但又觉得一个个填 Jira 里面的选项太麻烦,那就可以拷贝一个别人的,然后根据新项目的实际情况,将相应的配置改改。

Linux 就是这样想的。当父进程调用 fork 创建进程的时候,子进程将各个子系统为父进程创建的数据结构也全部拷贝了一份,甚至连程序代码也是拷贝过来的。按理说,如果不进行特殊的处理,父进程和子进程都按相同的程序代码进行下去,这样就没有意义了。

所以,我们往往会这样处理:对于 fork 系统调用的返回值,如果当前进程是子进程,就返回 0;如果当前进程是父进程,就返回子进程的进程号。这样首先在返回值这里就有了一个区分,然后通过 if-else 语句判断,如果是父进程,还接着做原来应该做的事情;如果是子进程,需要请求另一个系统调用execve来执行另一个程序,这个时候,子进程和父进程就彻底分道扬镳了,也就产生了一个分支(fork)了。

同样是“先拷贝,再修改”的策略,你可能会问,新进程都是父进程 fork 出来的,那到底谁是第一个呢?

作为一个外包公司老板,有了新项目当然会分给手下做,但是当公司刚起步的时候呢?没有下属,只好自己上了。先建立项目运行体系,等后面再做项目的时候,就都按这个来。

对于操作系统也一样,启动的时候先创建一个所有用户进程的“祖宗进程”。这个在讲系统启动的时候还会详细讲,我这里先不多说。

有时候,父进程要关心子进程的运行情况,这毕竟是自己身上掉下来的肉。有个系统调用waitpid,父进程可以调用它,将子进程的进程号作为参数传给它,这样父进程就知道子进程运行完了没有,成功与否。

所以说,所有子项目最终都是老板,也就是祖宗进程 fork 过来的,因而它要对整个公司的项目执行负最终的责任。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值