PCB(进程)包含的内容:对应的代码和数据位置,进程标识符(pid),进程优先级信息,进程状态信息,内存指针,上线问(CPU各种寄存器),记账信息,其他…
fork之前的父进程独立执行,fork之后,父子连个执行流分别执行,从fork之后执行,谁先执行完全由调度决定
fork的返回值:子进程返回0,父进程返回子进程的pid,小于零表示进程创建失败
vfork和fork的用法大致相同
区别:
1. 保证子进程先执行,在子进程调用exec&_exit之后释放(这个过程将main的栈帧释放,所以当父进程再次调用到vfork之前的变量时候,就会出现段错误),vfork之后的主函数不再是父进程的函数体,已被破坏之后,父进程才可以被调度执行
2. 创建一个子进程,而子进程和父进程共享地址空间,而fork的子进程有独立地址空间
vfork为什么必须调用exit退出?
进程终止场景:
- 代码运行完毕,结果正确
- 代码运行完毕,结果不正确
- 代码异常终止
进程正常退出:
- 从main return 0 ,结果正确
- 调用exit(0)
- 调用_exit(0)
ps:exit():终止当前进程,exit(n),n表示进程的退出码(进程的返回值|执行结果),exit调用_exit()
- 执行用户的清理函数
- 刷新缓冲区,关闭流(文件流),_exit并不进行此操作
- 调用退出函数atexit&onexit
结果不正确:
- 从main return !=0 ,结果正确
- 调用exit(!=0)
- 调用_exit(!=0)
异常退出:
Ctrl+c 信号终止
使用echo $ ? 查看上一个进程的运行结果
异常终止:
异常终止之后使用kill命令强行终止进程.
作用:父进程通过进程等待拿到子进程的结果,通过进程等待,避免僵尸进程,保证子进程先执行,父进程后执行
(1)wait(阻塞等待)
执行逻辑:
1. 子进程还没有终止,父进程就会阻塞在wait函数中,直到子进程终止,父进程才从wait函数中返回
2. 调用wait函数时,子进程其实已经执行完毕名字进程成为了僵尸进程,wait立刻返回,拿到子进程的退出信息,并且释放子进程的相关资源
3. 调用wait的进程并没有子进程,wait函数返回-1,表示调用失败.
wait函数的返回值调用成功时是等待的子进程的pid.
函数原型:pid_t wait(int *status)
status的值相当于exit(n) n&0x7f之后的值,不为0表示进程异常退出,具体的值表示该进程退出的信号的编号.次第八位表示进程退出码,被那个信号退出
输出型参数,有操作系统填充,获取任意子进程退出状态,不关心则可以设置成NULL
(2)wait_pid(非阻塞等待)
如果要等待的子进程已经执行完了,那么wait_pid就返回子进程的pid同时释放子进程对应的资源.如果还没有执行完,wait_pid就会立刻返回,返回值为0.
函数原型pid_t wait_pid(pid,int &status*status,WNOHANG)
exec函数组无返回值,因为被替换哼了目标程序的代码
l:列表形式出入argv
v:数组形式传入argv
e:使用自定义的环境变量
p:自动在pase中寻找可执行文件
execl,execlp.execle
execv,execvp,execve