一、铺垫
1.进程在创建进程会存在"血缘"关系—父进程、子进程
2.进程的独立性是非常高的,子进程的异常退出,是不会影响到父进程的;但是父进程可以通过接口(函数)来判定,子进程是否是异常退出;
3.创建子进程时,虽然拷贝了父进程的一切相关的PCB(进程控制块,数据段、代码段、页表等等一系列数据),但仍旧是有不同的,比如说PID,PPID(包括但不限于这些);而且采用了写时拷贝技术,会对一些变量等进行处理;来变更各自的数据;
4.父子进程共享代码段,因为这部分编译好之后,不会被二次修改;数据段在fork()之后是逻辑上被复制了,物理内存上并不会立即被复制,现代操作系统通常会使用“写时拷贝”{COW缩写(Copy-On-Write)}机制,当父子进程尝试修改这部分数据时,才会真正的复制相应的数据到物理内存中,在此之前,父子进程共享同一份物理内存的数据段;
5.为什么子进程中,采用exit()来退出进程,而不采用return的方式?
答:子进程在父进程中被调用,并采用exit()函数退出子进程,他的返回值会返回给父进程,如果采用return的形式,他的返回值,会返回给子进程的主函数main;
main()主函数中的return 他的作用类似于调用exit()函数,返回值给main();
//写一段伪代码来理清逻辑关系
pid_t tid;
tid=fork()
if(tid==0){//子进程
exit(1);
}
else if(tid>0){//父进程
return 0;
}
else{//创建失败
}
二、创建子进程
#include <unistd.h> //头文件
pid_t fork(void); //创建子进程
pid_t 子进程的进程ID;源类型是int;
返回值:
若成功:父进程返回子进程的ID;子进程返回0;若失败则返回-1;错误码被设立;
三、获取进程ID
#include <sys/types.h>· //头文件
#include <unistd.h>pid_t getpid(void); //获取当前进程ID
pid_t getppid(void); //获取父进程ID
四、退出函数
4.1_exit()函数
#include <unistd.h>void _exit(int status);参数: status 定义了进程的终止状态,父进程通过 wait 来获取该值
4.2exit()函数
#include <unistd.h>void exit(int status);
exit最后也会调用_exit(), 但在调用exit之前,还做了其他工作:
4.3return退出
五、进程回收
5.1wait()函数
#include<sys/types.h> //头文件#include<sys/wait.h>pid_t wait(int*status);返回值:成功返回被等待进程 pid ,失败返回 -1 。参数:输出型参数,获取子进程退出状态 , 不关心则可以设置成为 NULL
5.2pidwait()函数
pid_ t waitpid(pid_t pid, int *status, int options);