你要选择哪条路?
在我们这个世界中, 操作系统老大绝对是最神秘的,我们这些进程想和他通信,只能通过那所谓的系统调用,例如open,close, socket,connect 等等。
我对自己的一亩三分地非常熟悉,这是一个地址空间,虽说是虚拟的,但是我却并不在意。
这个地址空间被划分成若干区域:
我的工作就是配合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先生的工作不就是创建新进程的吗?” 阿甘反问。
“创建的新进程和我有什么关系?”
“当然属于你的子进程啊, 这个子进程也有自己的一亩三分地, 但是复制了你的栈,堆和数据区,不过他和你共享了代码段。”
“共享了老子的代码段? 我怎么不知道?”
“你当然不知道了喽,不过这对你也没有影响啊,那个fork调用如果创建子进程成功,给你返回的就是子进程的进程号了,给子进程返回的值就是0。”
“你就胡扯吧, 一个fork调用能返回两次? ” 我绝不相信, 这完全颠覆了我的世界观。
“信不信由你, 反正子进程创建以后,由于和你是共享了代码段,也会从pid=fork()这一行代码处开始执行,只不过子进程得到的pid是0,所以就走了第二个分支!”
我现在有点理解爱吟唱的诗人Fork先生了,他的的确确是返回了两次,每个进程一次。
怪不得他整天吟唱“ 一片树林里分出两条路......” 这可不就是两条路啊,只不过我们没得选择。
我甚至能想象得出他像问我一样故意问子进程要走那条路,子进程每次都得走第二个分支。
我还注意到我的那个局部变量count = 10 ,也被复制到了子进程的栈中,很明显,子进程会把它减去1,变为9。 我这里则会加上1, 变成11, 我们两个互不影响。
我好奇地问阿甘:“我的子进程共享我的代码段,我们都执行一模一样的代码,似乎没什么意义啊!”
阿甘说:“我阅代码无数,能从无数指令中总结出你们进程的目的, 我估计你啊就是一个Web服务器程序,你就是等待客户端的请求,请求来了以后你用fork创建子进程去处理(进入了代码的另外一个分支),然后你继续等待。”
我觉得阿甘说得很有道理,可还是追问道:“要是新fork的进程确实需要执行新的程序呢?”
阿甘说道:“那就是另外一个系统调用exec了, 这位先生可以把装载新的程序,替换掉进程的代码段中的代码,重置栈,堆和数据段,一切从头开始。”
在对操作系统老大增加了几分敬畏之情的同时, 我暗自感慨,没想到创建一个新的进程,背后要发生这么多的事情啊。
(完)
你看到的只是冰山一角, 更多精彩文章,请移步《2016文章精华》或者《2017文章精华》
码农翻身
用故事讲述技术