进程的创建:
在Linux下 fork 函数 可用于创建进程,他从已存在的进程中创建一个新的进程。新进程为子进程,原进程为父进程.
该函数没有参数返回值类型为 pid_t, 返回值如果小于0说明进程创建失败,返回值如果等于0则说明是子进程,返回值如果大于0则是父进程。(父进程返回的是子进程的pid)
fork之后就会有两个二进制代码相同的进程,而且都运行到相同的地方。下面我们来使用fork。
可以看出运行之后fork之前父进程独立运行,fork之后父子两个进程执行流分别执行,fork之后谁先执行由调度器决定。
一个父进程创建一个子进程之后,通常代码是共享的然会数据会以写实拷贝的方式各自私有一份。
当然进程也有可能创建失败当fork返回值小于0是则创建失败,失败的原因主要有两点
1.系统中有太多的进程。
2. 实际用户的进程数超过了限制。
创建进程还有一个函数 vfork,也是用来创建子进程但是与fork有两点不同
1.vfork创建子进程,而子进程和父进程共享地址空间,而fork的子进程具有独立的空间地址。
2.vfork保证子进程先运行但他退出后父进程才能被调度运行,而fork之后父子进程谁先运行完全由调度器决定。
进程等待:
进程等待的必要性:
1.子进程退出,父进程如果不回收则会出现僵尸进程,造成内存泄漏。
2.我们需要知道子进程的状态和是否正常退出。
3.父进程通过等待的方式,回收子进程的资源,获取子进程的退出信息。
进程等待的方法: 函数wait用于进程等待 wait的参数是输出型的参数,如果不关心可以设置为NULL。
还有一个函数waitpid.
#include<sys/types.h>
#include<sys/wait.h>
定义函数 pid_t waitpid(pid_t pid,int * status,int options);
返回值说明: 当正常返回时,返回收集的子进程的pid
如果没有可收集的已退出的子进程则返回0。
如果出错则返回-1。
pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。
pid=-1 等待任何子进程,相当于 wait()。
pid=0 等待进程组识别码与目前进程相同的任何子进程。
如果子进程已经退出,调用这两个函数时会立即返回,并释放资源,获得子进程退出信息。
如果在任意时刻调用,子进程存在且正常运行,则进程可能阻塞。
如果不存在该子进程,则立刻出错返回。
进程终止:
进程退出的场景
1.代码运行完毕,结果正确
2.代码运行完毕,结果不正确
3.代码异常终止
正常终止的话我们可以通过 echo$? 查看进程的退出码。
1.从main函数返回
2.调用exit
3.调用_exit
exit 和 _exit 函数的区别时 exit会刷新输出缓冲器。
异常情况就是信号终止。
return退出执行return n 就等同于exit(n),因为调用main的运行时函数会将main的返回值当做exit的参数。