前言
这里是偶尔呆蠢的小年糕童鞋,虽然是课内的实验,但是想好好完成然后研究一番,也算是珍惜一个机会来提升一下自己的理解吧(๑•̀ㅂ•́)و✧。本实验主要是在Linux下进行的一些小编程实验,来搞懂一些关于进程的知识。
疑问の产生
首先,我拿到了老师给我们的实验指导书,乍一看这个程序很简单:
后来会发现运行结果是
很奇怪,在一般我们的认知中会认为它只会执行if分叉的其中一个。肯定关键出在对fork()函数的理解上(毕竟咱以前没接触过b( ̄▽ ̄)d)。
对fork()の调查
看了一些大触的博客上说调用fork()函数之后:
系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
再结合fork()的返回值来判断:
在父进程中,fork返回新创建子进程的进程ID;在子进程中,fork返回0;如果出现错误,fork返回一个负值;
我还是有点朦朦胧胧的感觉,后来自己写了一个很傻的程序来测试:
几乎在每一步都插入了一句输出。
while()函数是为了延长运行的时间,来分清楚它们到底是不是并行程序。
然后我们来看结果:
我们就会发现,子程序确实像复制了一份父进程,输出的内容都和父进程一样(除了用来区分的标识外,3657是父进程新创建子进程的进程ID,0是子进程运行时出现的。),而且也真是子程序和父程序并行的(看出现了两个start哦)。
但是通过查询资料后,会发现,其实子进程在复制父进程的时候,是会从父进程运行到的地方继续运行,也就是它把父进程运行的记录指针也复制了一份。所以如果在这个程序开头加上一句输出,在子进程中是不会显示的。
另外,我们又产生了疑问?
为什么会出现[root@localhost cpp]这个东西??
百度之后得知,shell会监听它运行进程(也就是这个父进程)的结束,当输出last 3657的时候,父进程也就结束了,这个时候系统就自动输出[root@localhost cpp]了!
那么子进程呢?
因为shell不会关心这个父进程自己又新创建的进程,所以当父进程结束之后,这个子进程被自动归为系统进程,所以父进程结束之后,子进程还能继续运行完。
那我们再试试,在这段程序的最后加上一句
wait(0);
运行结果如下:
wait(0)的作用是等待所有的子进程都运行完毕,所以这个时候,它就没有出现像刚才那样的情况了。
其他の扩展
这个时候我们再来看看其他几个实验:
这个和我们一开始的很像,程序会创建一个子程序,子程序和父程序的是并行的,但是一般情况下因为速度很快,所以两个交叉的可能性不大。所以我们就能大概理解这个结果了。
这个程序多了一句exit(0),可以退出子程序,所以我们可以猜到子进程就会输出xb,父进程输出xay。
结束语
小年糕写的可能不完全对QAQ,如果有错误偏差欢迎大家给我指正( ̄▽ ̄),如果你有同样的疑惑,不知道你看懂了我说的了吗,嘻嘻,总之谢谢你的观看。