一、进程创建
1、fork()函数
在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
#include <unistd.h>
pid_t fork(void);
返回值:自进程中返回0,父进程返回子进程id,出错返回-1
进程调用fork,当控制转移到内核中的fork代码后,内核会做一下动作:
1、分配新的内存块和内核数据结构给子进程。
2、将父进程部分数据结构内容拷贝至子进程。
3、添加子进程到系统进程列表当中。
4、fork返回,开始调度器调度。
fork()如何运行该看下图:
2、fork()函数的返回值
子进程返回0。
父进程返回的是子进程的pid。
fork()常规用法
1、一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。
2、一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。
fork()调用失败的原因
系统中有太多的进程。
实际用户的进程数超过了限制。
二、进程终止
1、进程退出场景几种情况
代码运行完毕,结果正确
代码运行完毕,结果不正确
代码异常终止
常见退出方式
- 从main返回
- 调用exit
- _exit
2、exit()函数
#include <unistd.h>
void _exit(int status);
参数:status 定义了进程的终止状态,父进程通过wait来获取该值;
注意!!
exit最后也会调用exit, 但在调用exit之前,还做了其他工作:
1. 执行用户通过 atexit或on_exit定义的清理函数。
2. 关闭所有打开的流,所有的缓存数据均被写入
3. 调用_exit
3、return退出
return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返回值当做 exit的参数。
三、进程等待
1、wait
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int*status);
返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
2、waitpid
pid_ t waitpid(pid_t pid, int *status, int options);
返回值:
当正常返回的时候waitpid返回收集到的子进程的进程ID;
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
学习总结,有缺陷还请大佬指出。