进程创建,进程等待,进程终止,进程程序替换

进程创建

1.在Linux中,bash是shell的一种,它也是由操作系统创建的一个进程,但是它不可能完成操作系统给它每一个任务,所以它需要创建多个子进程完成任务,它只需要等待(进程等待),那如何创建进程呢?

第一种fork:当我们调用fork后,内核做几件事情:

                                                                                        分配新的内存块和内核数据给子进程

                                                                                        将父进程部分数据结构内容拷至子进程

                                                                                         添加子进程到系统进程列表中

                                                                                         fork返回,开始调度器调度(可以理解成优先级调度)

fork的返回值有两个:子进程返回0,父进程返回子进程的pid,其实这不难理解,相当于一模一样的进程在同时跑,代码是一摸一样的,数据是自己私有的罢了,所以肯定有两个返回值了。fork失败返回-1,可能原因是进程太多,系统资源不够等。

写时拷贝

刚才我们提到代码是共享的,数据是私有的,那么它到底是怎么回事?

我们知道代码是放在物理内存中的,既然创建子进程后代码是一样的,那么操作系统就只需让父进程和子进程通过页表都映射到相同的位置即可,但是子进程和父进程的pid,或者执行的代码不同,所以他们的数据肯定是不同的,所以数据是私有的,当他们在读代码的时候,任意一方试图写入,此时,物理内存才给他们开辟一块空间,各自写各自的,这就是写时拷贝。

第二种方式vfork:与fork区别在于先让子进程执行,然后在执行父进程。具体点:只需要改变父进程的状态,变为S,子进程结束,再变为R。还有就是vfork的子进程和父进程共享程序地址空间

进程终止

进程终止三种情况:

 1.代码运行完了,结果正确  退出码为0;

2.代码运行完了,结果错误,退出码非0;

3.代码异常终止

正常终止的几种方式:return ,exit,_exit(退出后不刷新缓冲区)

进程等待

为什么会有进程等待?

1.父进程需要子进程把事情干完了没,回收退出码,检测是否异常。

2.需要回收子进程,防止子进程变为僵尸进程,内存泄漏

方式:阻塞式,一直等待子进程返回退出码。

          非阻塞式:访问一下,如果没有退出,直接返回,过一会儿时间再访问,这种方式称为轮询式访问。

具体如何回收:

                        通过系统调用接口wait(int *status)或者waitpid(pid_t pid ,int *status,int options);

                       这里的status是状态退出的信息,低八位是信号异常的信息,没有收到信号的话,是正常退出,高八位是退出码。

                       options是一个宏,它替换的是轮询式访问。pid是-1的话是等待任意一个子进程,不然的话,是其他进程

进程程序替换

fork之后,子进程有可能和父进程执行的代码不一样,那么它就需要exec函数来完成程序替换,这个过程并没有创建进程。

共有6种exec函数,其他五中都是以execve系统调用接口而封装而来的。execl,execlp,execle,execv.execlp;l-代表是列表,v-代表的是数组,p-代表的是路径,e-代表的是环境变量

其实我们完全可以写一个简易的shell。

猜你喜欢

转载自blog.csdn.net/congjichukaishi/article/details/83044976