进程原语,linux操作系统提供的用于进程开发的一系列函数接口process_api
共有三代fork
第一代,完全拷贝
第二代,只完成子进程创建和PCB拷贝
第三代,读时共享,写时复制,当前最常用的版本
读时共享,当父进程创建子进程后,建立映射,可以让子进程通过映射内存访问父进程资源, 无需拷贝
写时复制, 当子进程写访问映射内存时 ,触发写复制, 父进程将子进程访问的部分数据拷贝给子进程
写复制操作对父子进程都有效, 只要修改映射, 都会触发复制
pid_t pid = fork(void);
在Liux文件系统中,/目录是所有文件夹或文件的父级
在Linux文件系统中,pid 1/sbin/init进程为根进程,是所有系统进程的父级
在父子进程间存在继承机制,任务或数据可以继承给子进程
在linux下是内存泄漏现象,开发时系统中申请的内存资源,使用完毕及时释放,否则进程持续占用内存,影响其他进程使用或影响内存重用性
子进程退出后,调用exit(0),进而系统调用EXIT(0),释放用户空间、释放内核空间,但是内核空间释放不完全,残留了PCB。子进程成为僵尸进程,造成内存泄露。
系统的所有进程结束后都会变成僵尸进程,是一种常态,一个必经环节。
僵尸进程的危害
内存泄露
占用PCB,影响创建新的进程
当产生僵尸进程后,父进程要对僵尸进程进行回收。父进程可以通过这个PCB,对PCB中子进程退出的原因进行采集(验尸)。
头文件sys/wait.h
pid_t zpid=wait(NULL);
调用一次,回收一个僵尸进程,如果有多个进程需要循环调用。
wait是阻塞函数,会等待子进程结束后进行回收
可以传入一个int* status去承接PCB中的信息,来实现验尸的目的,也可以传NULL放弃验尸。
后续通过status进行验证处理,获取子进程的退出原因
执行wait函数时,参数为null,表示只释放PCB内存,但是不采集子进程退出原因,不进行验尸操作
返回僵尸进程的pid
zpid>0 僵尸进程回收成功
zpid==-1 回收失败,原因:没有子进程却执行回收操作
运行态
僵尸态
回收后,子进程消失
注意:多进程模式中,子进程一定会变成僵尸进程,所以父进程必须进行回收操作
wait的升级版
pid_t zpid = waitpid(pid_t pid, int* status, WNOHANG);
waitpid更多的回收方式,还支持非阻塞回收。
WIFEXITED(status);
此函数可以判断子进程是否是正常退出,如果正常退出,此函数返回1
int code=WEXITSTATUS(status);
此函数可以从status提取进程的返回值或退出值,并返回
WIFSIGNALED(status);
此函数可以检测子进程是否被信号杀死(异常退出),如果是返回1
int signo=WTERMSIG(status);
此函数获取杀死子进程的信号编号并返回