目录
fork函数的使用
功能:创建子进程
头文件:#include<unistd.h>
返回值:pid_t相当于无符号整型,子进程返回0,父进程返回子进程的pid,假如进程创建失败返回-1
我们可以根据返回值来给子进程安排任务
fork函数内核的作用
1、将父进程的内存块和内存数据拷贝给子进程
2、将父进程部分数据拷贝进子进程
3、将子进程添加至进程列表中
4、fork返回,调度器调度
写时拷贝
为了节省内存空间,父子进程大部分时候都是使用同一个位置的代码,只有当父子进程中某些变量的值发生改变的时候,编译器为了让他们互不影响,就会发生写时拷贝
进程终止
程序终止有三种情况
1、代码跑完,结果正确
2、代码跑完,结果不正确
3、代码没跑完,程序崩溃(这个时候退出码没有意义,要看退出信号)
代码跑完,退出码
进程崩溃,信号
linux下查看退出码 echo $?
退出方式
main函数返回值为运行退出码,0为对,非0是不对,其他函数为函数返回,不是返回退出码
status传入返回的退出码
exit退出时候会刷新缓冲区,将缓冲区的内容输出(c语言提供的函数)
_exit退出时候不会刷新缓冲区(系统调用)
说明缓冲区是c语言所维护的,不是操作系统维护的
进程等待
假如我们不等待子进程退出,那么子进程会变成僵尸进程导致内存泄露
pid_t pid pid_t相当于无符号整型
pid > 0 等待指定进程
pid == -1 等待任意一个子进程退出 wait(int *status)函数,等待任意进程
int *status 通过传入变量地址获得退出码
WIFEXITED(status) 正常退出为真(查看是否正常退出)
WEXITSTATUS(status) 若非零,提取子进程退出码(查看进程退出码) 底层实现(status>>8)&0xFF
int option 等待的方式(阻塞和非阻塞)
options为0时候,是阻塞等待
WNOHANG 非阻塞等待
阻塞本质是进程阻塞在系统函数内部,阻塞等待一般都是在内核中阻塞,等待被唤醒
pid_t返回值
> 0 等待成功,子进程退出
== 0 等待成功,子进程未退出
v< 0 等待失败
进程替换
exec*系列的接口
其中execve是系统提供的接口,其他接口是通过execve函数进行封装的
参数:
const char *path 执行程序的目标路径(绝对路径和相对路径都可以)
const char *arg,... 传入的参数,是可变长参数,需要以NULL结尾
const char* file 会从环境变量中查找,会查找自己拥有的环境变量
char *const envp[] 会从传入的环境变量中进行查找,要自己配置环境变量
char *const argv[] 将传入参数整合成数组传入
返回值:
execl调用失败返回-1
调用成功没有返回值,因为替换成功后,ececl函数也被替换