你要选择哪条路?

在我们这个世界中, 操作系统老大绝对是最神秘的,我们这些进程想和他通信,只能通过那所谓的系统调用,例如open,close, socket,connect 等等。

我对自己的一亩三分地非常熟悉,这是一个地址空间,虽说是虚拟的,但是我却并不在意。

这个地址空间被划分成若干区域:

640?wx_fmt=png

我的工作就是配合CPU阿甘去执行代码区的那些代码,代码有时候非常简单,就是把一些数字加加减减; 有时候则是复杂的函数调用,这时候“栈”就得出马,把各种调用参数入栈,出栈; 有时候会动态分配一点内存,此时我的“堆”就要大显身手了。

让我感到奇怪的是,这些代码运行起来似乎无穷无尽,很久之后我才悟出来,其实我一直在一个循环中打转,人类故意让我走不出来。

这一次我遇到了一段代码:

pid_t pid;
int count = 10;
pid = fork();
if( pid >0 ){
  count++;
  printf("Parent process\n");  
  ...其他处理...
} else if (pid==0){
   count--;
   printf("Child process\n");
   ...其他处理...
} else{
    err_exit("error occured ");
}

当我准备按照之前的方式执行的时候,我遇到了系统调用Fork先生。

这位Fork先生根本就没有理我, 在那里不停地吟唱一首诗:

一片树林里分出两条路,

而我选择了人迹更少的一条,

从此决定了我一生的道路。

我不知道他为什么如此钟情于这首诗,只得提醒道:“嗨,哥们儿,要系统调用了啊。”

他瞥了我一眼:“你要选哪条路?”

哪条路?

我看了看自己的代码,确实有三个分支, 但是走哪个分支依赖于Fork先生返回给我的结果pid啊,我没得选择。

我把自己的想法告诉他。

Fork先生开始和操作系统老大通话,过了一会儿, 告诉我:“走第一个分支。”

然后他又开始吟唱那首诗了: 一片树林里分出两条路......

过了一会儿,我又要执行这段代码了,Fork先生还是问道:“你要选哪条路?”

我估计这厮太无聊,故意没事找事,就没搭理他。

他照例和操作系统老大通话后,告诉我:“走第一个分支。”

第3次,第4次,第5次...... 每次我执行这段代码,爱吟唱的Fork先生总是说:“走第一个分支。”

每次都是走第一个分支!

这不由得引起了我的怀疑: Fork先生是不是搞错了? 我怎么永远都走不到第二个分支去呢?  那第二个分支的代码有什么用处? 人类不会这么愚蠢地写无用的代码吧?

我偷偷问CPU阿甘:“兄弟, 我的第二个分支你执行过吗?”

CPU阿甘飞快地说:“当执行过!执行过好几次呢!”

这就见鬼了,Fork先生从来没让我走过第二个分支啊。

阿甘解释说:“不是在你这里执行的,是通过你fork出来的进程执行的。”

“我fork出的进程?”

“对啊, 那个Fork先生的工作不就是创建新进程的吗?”  阿甘反问。

“创建的新进程和我有什么关系?”

“当然属于你的子进程啊, 这个子进程也有自己的一亩三分地, 但是复制了你的栈,堆和数据区,不过他和你共享了代码段。”

640?wx_fmt=png

“共享了老子的代码段? 我怎么不知道?”

“你当然不知道了喽,不过这对你也没有影响啊,那个fork调用如果创建子进程成功,给你返回的就是子进程的进程号了,给子进程返回的值就是0。”

“你就胡扯吧, 一个fork调用能返回两次? ” 我绝不相信, 这完全颠覆了我的世界观。

“信不信由你, 反正子进程创建以后,由于和你是共享了代码段,也会从pid=fork()这一行代码处开始执行,只不过子进程得到的pid是0,所以就走了第二个分支!”

640?wx_fmt=png

我现在有点理解爱吟唱的诗人Fork先生了,他的的确确是返回了两次,每个进程一次。

怪不得他整天吟唱“ 一片树林里分出两条路......” 这可不就是两条路啊,只不过我们没得选择。

我甚至能想象得出他像问我一样故意问子进程要走那条路,子进程每次都得走第二个分支。

我还注意到我的那个局部变量count = 10 ,也被复制到了子进程的栈中,很明显,子进程会把它减去1,变为9。 我这里则会加上1, 变成11, 我们两个互不影响。

我好奇地问阿甘:“我的子进程共享我的代码段,我们都执行一模一样的代码,似乎没什么意义啊!”

阿甘说:“我阅代码无数,能从无数指令中总结出你们进程的目的, 我估计你啊就是一个Web服务器程序,你就是等待客户端的请求,请求来了以后你用fork创建子进程去处理(进入了代码的另外一个分支),然后你继续等待。”

我觉得阿甘说得很有道理,可还是追问道:“要是新fork的进程确实需要执行新的程序呢?”

阿甘说道:“那就是另外一个系统调用exec了, 这位先生可以把装载新的程序,替换掉进程的代码段中的代码,重置栈,堆和数据段,一切从头开始。”

在对操作系统老大增加了几分敬畏之情的同时, 我暗自感慨,没想到创建一个新的进程,背后要发生这么多的事情啊。

(完)

你看到的只是冰山一角, 更多精彩文章,请移步《2016文章精华》或者《2017文章精华


码农翻身

用故事讲述技术

640

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值