读时共享写时复制
单进程模式,一个父进程,父子进程映射就可以了,不需要共享。
不需要拷贝可以。可以直接用。
如果对子进程进行修改,一定是会断掉映射的。
修改了,就进行拷贝。
如果父进程修改了呢?
父进程修改时,要维护子进程的修改副本,因此,父进程修改的时候,也出发写拷贝。
否则会出现,父进程一直随着子进程在变化。很不好的情况。要及时备份,保证稳定性。
例如之前的代码,如果没有写时复制,那么每个子进程的i都是不变的。
waitpid
进程回收函数。
pid_t pid = waitpid(pid_t pid, int* status, int opt)
回收僵尸进程,支持非阻塞回收方案。
pid参数:
- 小于-1:指的是组,加负号就是组id,回收特定组里的id。跨组。
- 等于-1:回收任意子进程。任意。
- 等于0:同组回收,回收调用的进程。同组。
- 大于0:特定。
opt参数:opt=WNOHANG(非阻塞)
返回值:
- 大于0:成功了,返回的是僵尸进程的pid。
- 等于0:非阻塞,子进程无需回收。
- 等于-1:回收失败。
非阻塞,可以干点别的,可以让父进程交替工作。
阻塞,就得一直等着。
非阻塞的waitpid函数,使得更加灵活。
非阻塞轮询回收。
int main(void){
pid_t pid;
pid_t zpid;
int i=0;
for(i;i<5;++i){
pid=fork();
if(!pid)break;
}
if(pid>0){
printf("im father, and my pid is %d\n",getpid());
while((zpid=waitpid(-1,NULL,WNOHANG))!=-1){
if(zpid>0){
printf("parent wait zombie success...\n");
}else{
printf("parent running...\n");
sleep(1);
}
}
}else if(!pid){
printf("im child NO %d, and my pid is %d\n",i,getpid());
sleep(i);
exit(i);
}else{
perror("fork call failed\n");
exit(1);
}
return 0;
}
其中,在父进程当中,必须把zpid赋值的过程写进循环里。
因为每次都要进行一个赋值,然后判断,否则就死循环了。
输出结果:
LinuxDemo01
关于进程校验。