在linux中多进程的并发执行时,处理不当可能会出现 孤儿进程和僵尸进程;它们出现的情况如下:
1. 孤儿进程出现在: 父进程先于子进程结束时。(当用ps -a 时,可以看到父进程已不在了,而子进程依旧在的情形)
2.僵尸进程出现在:子进程先于父进程结束,而父进程未用 wait()或者waitpid(),来监听子进程的状态,使子进程的资源迟迟不能释放的情形;
(当用ps -a 查看时 那个僵尸进程的最后面将出现 defunc 的标志);
下面的一个成程来展示僵尸进程和孤儿进程的产生情形:
1. 孤儿进程出现在: 父进程先于子进程结束时。(当用ps -a 时,可以看到父进程已不在了,而子进程依旧在的情形)
/*** * 设有两个并发执行的父子进程,不断循环输出各自进程号、优先数和调度策略。 * 进程初始调度策略均为系统默认策略和默认优先级。 * 当某个进程收到SIGINT信号时会自动将其优先数加1, * 收到SIGTSTP信号时会自动将其优先数减1。请编程实现以上功能 * * ***/ #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<sched.h> #include<sys/resource.h> #include<sys/types.h> #include<sys/wait.h> #include<signal.h> #include<unistd.h> void priority_increase(); void priority_descrease(); int main(int argc, char* argv[]) { pid_t ppid, pid; ppid = getpid(); signal(SIGINT, priority_increase); //注册优先数加1的信号 signal(SIGTSTP, priority_descrease); //注册优先数减1的信号 if((pid=fork()) <0 ) { perror("the child process can't be created :"); exit(-1); }else { if( pid>0) { struct sched_param p; p.sched_priority = 0; //设置静态优先数 sched_setscheduler(ppid,SCHED_OTHER, &p); //设置调度 printf("father process pid: %d , schedule_policy: %d, priority: %d/n", ppid, sched_getscheduler(ppid), getpriority(PRIO_PROCESS, ppid) ); printf("child process pid: %d , schedule_policy: %d, priority: %d/n", pid, sched_getscheduler(pid), getpriority(PRIO_PROCESS, pid) ); int n; while(1) { sleep(1); scanf("%d", &n); switch(n) { case 1: kill(ppid, SIGINT); // 使父进程的优先数加1; break; case 2: kill(ppid, SIGTSTP); //使父进程的优先数减1; break; case 3: kill(pid, SIGINT); //使子进程的优先数加1 break; case 4: kill(pid, SIGTSTP); // 使子进程的优先数减1 break; default: //默认,其他数字退出该程序 //注释以下3句将产生孤儿进程,当父进程退出时,子进程还继续在执行; /* kill(pid, SIGQUIT); int ret; wait(&ret); */ return 0; } } } else { struct sched_param p; p.sched_priority = 0; sched_setscheduler(pid, SCHED_OTHER, 0); while(1) { pause(); } } } return 0; } void priority_increase() { setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid())+1 ); printf("process pid: %d , schedule_policy: %d, priority: %d/n", getpid(), sched_getscheduler(getpid()), getpriority(PRIO_PROCESS, getpid())); } void priority_descrease() { setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid())-1 ); printf("process pid: %d , schedule_policy: %d, priority: %d/n", getpid(), sched_getscheduler(getpid()), getpriority(PRIO_PROCESS, getpid())); }
2.僵尸进程出现在:子进程先于父进程结束,而父进程未用 wait()或者waitpid(),来监听子进程的状态,使子进程的资源迟迟不能释放的情形; /*** * 设有两个并发执行的父子进程,不断循环输出各自进程号、优先数和调度策略。 * 进程初始调度策略均为系统默认策略和默认优先级。 * 当某个进程收到SIGINT信号时会自动将其优先数加1, * 收到SIGTSTP信号时会自动将其优先数减1。请编程实现以上功能 * * ***/ #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<sched.h> #include<sys/resource.h> #include<sys/types.h> #include<sys/wait.h> #include<signal.h> #include<unistd.h> void priority_increase(); void priority_descrease(); int main(int argc, char* argv[]) { pid_t ppid, pid; ppid = getpid(); signal(SIGINT, priority_increase); //注册优先数加1的信号 signal(SIGTSTP, priority_descrease); //注册优先数减1的信号 if((pid=fork()) <0 ) { perror("the child process can't be created :"); exit(-1); }else { if( pid>0) { struct sched_param p; p.sched_priority = 0; //设置静态优先数 sched_setscheduler(ppid,SCHED_OTHER, &p); //设置调度 printf("father process pid: %d , schedule_policy: %d, priority: %d/n", ppid, sched_getscheduler(ppid), getpriority(PRIO_PROCESS, ppid) ); printf("child process pid: %d , schedule_policy: %d, priority: %d/n", pid, sched_getscheduler(pid), getpriority(PRIO_PROCESS, pid) ); int n; while(1) { sleep(1); scanf("%d", &n); switch(n) { case 1: kill(ppid, SIGINT); // 使父进程的优先数加1; break; case 2: kill(ppid, SIGTSTP); //使父进程的优先数减1; break; case 3: kill(pid, SIGINT); //使子进程的优先数加1 break; case 4: kill(pid, SIGTSTP); // 使子进程的优先数减1 break; default: //默认,其他数字退出该程序 //注释以下3句将产生孤儿进程,当父进程退出时,子进程还继续在执行; kill(pid, SIGQUIT); int ret; wait(&ret); return 0; } } } else { struct sched_param p; p.sched_priority = 0; sched_setscheduler(pid, SCHED_OTHER, 0); //注释下面的语句将出现僵尸进程,在父进程未退出之前 /* while(1) { pause(); } */ } } return 0; } void priority_increase() { setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid())+1 ); printf("process pid: %d , schedule_policy: %d, priority: %d/n", getpid(), sched_getscheduler(getpid()), getpriority(PRIO_PROCESS, getpid())); } void priority_descrease() { setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid())-1 ); printf("process pid: %d , schedule_policy: %d, priority: %d/n", getpid(), sched_getscheduler(getpid()), getpriority(PRIO_PROCESS, getpid())); }完整的实例:
/*** * 设有两个并发执行的父子进程,不断循环输出各自进程号、优先数和调度策略。 * 进程初始调度策略均为系统默认策略和默认优先级。 * 当某个进程收到SIGINT信号时会自动将其优先数加1, * 收到SIGTSTP信号时会自动将其优先数减1。请编程实现以上功能 * * ***/ #include<stdio.h> #include<stdlib.h> #include<errno.h> #include<sched.h> #include<sys/resource.h> #include<sys/types.h> #include<sys/wait.h> #include<signal.h> #include<unistd.h> void priority_increase(); void priority_descrease(); int main(int argc, char* argv[]) { pid_t ppid, pid; ppid = getpid(); signal(SIGINT, priority_increase); //注册优先数加1的信号 signal(SIGTSTP, priority_descrease); //注册优先数减1的信号 if((pid=fork()) <0 ) { perror("the child process can't be created :"); exit(-1); }else { if( pid>0) { struct sched_param p; p.sched_priority = 0; //设置静态优先数 sched_setscheduler(ppid,SCHED_OTHER, &p); //设置调度 printf("father process pid: %d , schedule_policy: %d, priority: %d/n", ppid, sched_getscheduler(ppid), getpriority(PRIO_PROCESS, ppid) ); printf("child process pid: %d , schedule_policy: %d, priority: %d/n", pid, sched_getscheduler(pid), getpriority(PRIO_PROCESS, pid) ); int n; while(1) { sleep(1); scanf("%d", &n); switch(n) { case 1: kill(ppid, SIGINT); // 使父进程的优先数加1; break; case 2: kill(ppid, SIGTSTP); //使父进程的优先数减1; break; case 3: kill(pid, SIGINT); //使子进程的优先数加1 break; case 4: kill(pid, SIGTSTP); // 使子进程的优先数减1 break; default: //默认,其他数字退出该程序 //注释以下3句将产生孤儿进程,当父进程退出时,子进程还继续在执行; kill(pid, SIGQUIT); int ret; wait(&ret); return 0; } } } else { struct sched_param p; p.sched_priority = 0; sched_setscheduler(pid, SCHED_OTHER, 0); //注释下面的语句将出现僵尸进程,在父进程未退出之前 while(1) { pause(); } } } return 0; } void priority_increase() { setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid())+1 ); printf("process pid: %d , schedule_policy: %d, priority: %d/n", getpid(), sched_getscheduler(getpid()), getpriority(PRIO_PROCESS, getpid())); } void priority_descrease() { setpriority(PRIO_PROCESS, getpid(), getpriority(PRIO_PROCESS, getpid())-1 ); printf("process pid: %d , schedule_policy: %d, priority: %d/n", getpid(), sched_getscheduler(getpid()), getpriority(PRIO_PROCESS, getpid())); }
关于僵尸进程的更多信息:
浅议Unix的defunct进程(“僵尸”进程) | ||
本文出自:http://www2.ccw.com.cn 作者: 张道新 赵国明 (2002-04-17 08:02:00) | ||
|
上文的原始链接:http://fanqiang.chinaunix.net/a1/b5/20020417/080200185.html