- 创建进程(fork)
- 进程的等待(wait)
- 进程终止(exit)
- 封装fork/wait
1.创建进程(fork)
fork的运行规则:
- 以父进程为模板,创建子进程
- fork会把父进程的PCB拷贝一份,稍加修改成为子进程的PCB
- fork会把父进程的虚拟地址空间拷贝一份,作为子进程的虚拟地址空间
- 父子进程会共用一份代码和数据,如果发生修改会给拷贝一份数据(写时拷贝)
- fork有两个返回值 父进程返回子进程的pid,子进程返回0,在fork之后分别继续执行
2.进程的等待(wait/waitpid)
进程等待的必要性:
- 如果子进程退出,父进程不关心就会导致僵尸进程,内存泄漏问题
- 如果导致僵尸进程,kill -9都不会杀死,因为谁也没办法杀死一个已经死去的进程
- 父进程要知道交代子进程的任务完成的怎么样了
- 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息
3.进程终止
正常退出:
- 代码执行完的情况
- 1.main()函数返回 能刷新缓冲区
0-------正确 非0 -------错误- 2.exit 库函数 本质是调用_exit exit结束前会关闭所有流再调用_exit
- 3._exit 进程退出 系统调用
异常退出:
- ctrl+c 信号终止
4.封装fork/wait
编写函数 process_create(pid_t* pid, void* func, void* arg), func回调函数就是子进程执行的入口函数, arg是传递给func回调函数的参数.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
typedef void (*FUNC)(void *);
void func(void* arg)
{
printf("%s\n",arg);
}
void process_create(pid_t* pid, void* func,char* arg)
{
*pid = fork();
if(*pid<0){
perror("error");
exit(-1);
}
else if(*pid == 0){
//child
FUNC funct = (FUNC)func;
funct(arg);
sleep(5);
}
else{
//father
pid_t ret = wait(NULL);
printf("chirld: %d\n",ret);
}
}
int main()
{
pid_t pid;
char* arg = "child";
process_create(&pid,func,arg);
return 0;
}