一个Linux守候进程例子,避免产生僵死进程
2012-03-15 13:29
489 查看
在前一部分提到了僵死进程的概念,如果我们写一个进程,这个进程fork 了一个新的子进程。而,我们不想等待这个进程完全结束,不想在主程序结束时,这个子进程变成僵死进程。利用量词调用 fork 可以达到这一目标。
下面为一个例子,及解释:
[cpp] view
plaincopy
#include<stdio.h>
#include<sys/wait.h>
int main(int argc, char **argv[])
{
pid_t pid;
printf("Main pid is %d./n",getpid());
pid = fork();/*第一个子进程,用来产生第二个子进程,提前与第二个子进程退出*/
if(pid < 0)
{
printf("fork error/n");
exit(1);
}
else if(pid == 0 )/*第一个子进程中执行*/
{
printf("child pid is %d,and my ppid is %d./n",getpid(),getppid());
pid = fork();/*产生第二个子进程,作为最终的目标进程*/
if(pid < 0)
{
printf("fork error/n");
exit(1);
}
else if(pid > 0)/*在第一个子进程退出*/
{
printf("child pid is %d,and my ppid is %d,i will die./n",getpid(),getppid());
exit(0);
}
sleep(2);/*第二个子进程休眠2秒,等待其父进程结束后,第二个子进程成为init进程的子进程,避免第二个成为僵死进程*/
printf("second child,my pid is %d, parent pid = %d/n", getpid(),getppid());
exit(0);
}
/*在主进程中执行,等待第一个子进程结束,避免第一个进程成为僵死进程*/
if (waitpid(pid, NULL, 0) != pid)
{
printf("waitpid error/n");
exit(1);
}
printf("My pid is %d,i have waitted %d died./n",getpid(),pid);
return 0;
}
在 Ubuntu10.4上的结果:
Main pid is 2736.
child pid is 2737,and my ppid is 2736.
child pid is 2737,and my ppid is 2736,i will die.
My pid is 2736,i have waitted 2737 died.
second child,my pid is 2738, parent pid = 1
总结:
在程序中,主程序中等待了第一个子进程结束,使第一个子进程不会产生僵死。在第一个子进程中,产生第二个子进程。第二个子进程休眠 2秒,等待其父进程(第一个子进程)结束。这是第二个子进程由于在退出前,其父进程提前结束,其父进程变为init。避免产生僵死。为最终需要的目标进程。
在设计中,如果需要一个进程运行时间很长,并且避免产生僵死,则可以在第二个子进程中执行需要的指令。
[cpp] view
plaincopy
#include<stdio.h>
#include<unistd.h>
#include<sys/resource.h>
#include<fcntl.h>
#include<signal.h>
#include<syslog.h>
void daemon_init(const char * cmd);
int main(int argc, char * argv[])
{
daemon_init("liyachao_d");
time_t ticks;
while(1)
{
sleep(60);
ticks = time(NULL);
syslog(LOG_INFO,"%s",asctime(localtime(&ticks)));
}
return 0;
}
void daemon_init(const char * cmd)
{
int i;
int fd0;
int fd1;
int fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
/*清空文件默认生成权限*/
umask(0);
/*取得最大的文件描述符*/
if(getrlimit(RLIMIT_NOFILE,&rl) < 0 )
{
printf("can't get file limit.");
}
pid = fork();
if(pid < 0 )
{
printf("fork error.");
exit(1);
}
else if(pid > 0)
{
exit(0);
}
setsid();
/*
Ensure future opens won't allocate controlling TTYs.
*/
sa.sa_handler =SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP,&sa,NULL) < 0 )
{
printf("catn't ignore SIGHUP");
exit(1);
}
pid = fork();
if(pid < 0 )
{
printf("child fork error.");
exit(1);
}
else if(pid > 0)
{
exit(0);
}
/*改变工作目录到root*/
if(chdir("/") < 0 )
{
printf("can't change directory to /");
exit(1);
}
/*关闭所有的文件描述符*/
if (rl.rlim_max == RLIM_INFINITY)
{
rl.rlim_max = 1024;
}
for (i = 0; i < rl.rlim_max; i++)
{
close(i);
}
/*重定向文件描述符0,1,2,到/dev/null*/
fd0 = open("/dev/null",O_RDWR);
fd1 = open("/dev/null",O_RDONLY);
fd2 = open("/dev/null",O_RDWR);
openlog(cmd, LOG_CONS, LOG_DAEMON);
/*初始化日志文件*/
if (fd0 != 0 || fd1 != 1 || fd2 != 2)
{
syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
exit(1);
}
}
下面为一个例子,及解释:
[cpp] view
plaincopy
#include<stdio.h>
#include<sys/wait.h>
int main(int argc, char **argv[])
{
pid_t pid;
printf("Main pid is %d./n",getpid());
pid = fork();/*第一个子进程,用来产生第二个子进程,提前与第二个子进程退出*/
if(pid < 0)
{
printf("fork error/n");
exit(1);
}
else if(pid == 0 )/*第一个子进程中执行*/
{
printf("child pid is %d,and my ppid is %d./n",getpid(),getppid());
pid = fork();/*产生第二个子进程,作为最终的目标进程*/
if(pid < 0)
{
printf("fork error/n");
exit(1);
}
else if(pid > 0)/*在第一个子进程退出*/
{
printf("child pid is %d,and my ppid is %d,i will die./n",getpid(),getppid());
exit(0);
}
sleep(2);/*第二个子进程休眠2秒,等待其父进程结束后,第二个子进程成为init进程的子进程,避免第二个成为僵死进程*/
printf("second child,my pid is %d, parent pid = %d/n", getpid(),getppid());
exit(0);
}
/*在主进程中执行,等待第一个子进程结束,避免第一个进程成为僵死进程*/
if (waitpid(pid, NULL, 0) != pid)
{
printf("waitpid error/n");
exit(1);
}
printf("My pid is %d,i have waitted %d died./n",getpid(),pid);
return 0;
}
在 Ubuntu10.4上的结果:
Main pid is 2736.
child pid is 2737,and my ppid is 2736.
child pid is 2737,and my ppid is 2736,i will die.
My pid is 2736,i have waitted 2737 died.
second child,my pid is 2738, parent pid = 1
总结:
在程序中,主程序中等待了第一个子进程结束,使第一个子进程不会产生僵死。在第一个子进程中,产生第二个子进程。第二个子进程休眠 2秒,等待其父进程(第一个子进程)结束。这是第二个子进程由于在退出前,其父进程提前结束,其父进程变为init。避免产生僵死。为最终需要的目标进程。
在设计中,如果需要一个进程运行时间很长,并且避免产生僵死,则可以在第二个子进程中执行需要的指令。
[cpp] view
plaincopy
#include<stdio.h>
#include<unistd.h>
#include<sys/resource.h>
#include<fcntl.h>
#include<signal.h>
#include<syslog.h>
void daemon_init(const char * cmd);
int main(int argc, char * argv[])
{
daemon_init("liyachao_d");
time_t ticks;
while(1)
{
sleep(60);
ticks = time(NULL);
syslog(LOG_INFO,"%s",asctime(localtime(&ticks)));
}
return 0;
}
void daemon_init(const char * cmd)
{
int i;
int fd0;
int fd1;
int fd2;
pid_t pid;
struct rlimit rl;
struct sigaction sa;
/*清空文件默认生成权限*/
umask(0);
/*取得最大的文件描述符*/
if(getrlimit(RLIMIT_NOFILE,&rl) < 0 )
{
printf("can't get file limit.");
}
pid = fork();
if(pid < 0 )
{
printf("fork error.");
exit(1);
}
else if(pid > 0)
{
exit(0);
}
setsid();
/*
Ensure future opens won't allocate controlling TTYs.
*/
sa.sa_handler =SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP,&sa,NULL) < 0 )
{
printf("catn't ignore SIGHUP");
exit(1);
}
pid = fork();
if(pid < 0 )
{
printf("child fork error.");
exit(1);
}
else if(pid > 0)
{
exit(0);
}
/*改变工作目录到root*/
if(chdir("/") < 0 )
{
printf("can't change directory to /");
exit(1);
}
/*关闭所有的文件描述符*/
if (rl.rlim_max == RLIM_INFINITY)
{
rl.rlim_max = 1024;
}
for (i = 0; i < rl.rlim_max; i++)
{
close(i);
}
/*重定向文件描述符0,1,2,到/dev/null*/
fd0 = open("/dev/null",O_RDWR);
fd1 = open("/dev/null",O_RDONLY);
fd2 = open("/dev/null",O_RDWR);
openlog(cmd, LOG_CONS, LOG_DAEMON);
/*初始化日志文件*/
if (fd0 != 0 || fd1 != 1 || fd2 != 2)
{
syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2);
exit(1);
}
}
相关文章推荐
- UNIX环境高级编程有一个例子说fork两次可以避免产生僵死进程,我不知道,为什么fork两次就能避免僵死进程?
- (转载)Linux僵死进程的产生与避免
- 避免linux系统调用fork后产生僵死进程
- Linux环境下僵死进程的产生及其避免
- 【linux】——linux僵死进程的产生与避免
- linux僵死进程的产生与避免
- 一个Linux守候进程例子
- linux僵死进程的产生与避免
- linux僵死进程的产生与避免
- linux避免僵死进程方法总结
- linux僵尸进程产生的原因以及如何避免产生僵尸进程
- 一个Linux内核利用init_task进行进程管理的简单例子
- linux 一个简单的进程创建例子
- Linux 僵尸进程产生及如何避免
- exec系类函数实例---产生一个僵死进程
- Linux如何避免僵死进程
- linux僵尸进程产生的原因以及如何避免产生僵尸进程
- Linux编写一个孤儿进程,这个孤儿进程可以同时创建100个僵死进程。
- 一个Linux内核利用init_task进行进程管理的简单例子
- Linux僵尸进程产生及如何避免2