snifer

【原创】嵌入式系统中守护进程的编写及调试

0
阅读(2134)

守护进程是Linux系统开发中很重要的知识点,很多朋友对这个问题掌握的不是很深入,今天我就写写这方面的问题,可以帮助大家熟悉守护进程的编写过程。

守护进程编写的主要步骤如下:

1.屏蔽一些有关控制终端操作的信号。防止在守护进程没有正常运转起来时,控制终端受到干扰退出或挂起。

signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGHUP ,SIG_IGN);

2.程序进入后台执行。由于守护进程最终脱离控制终端,到后台去运行。方法是在进程中调用fork使父进程终止,让Daemon在子进程中后台执行。这就是常说的脱壳。子进程继续函数fork()的定义如下:
pid_t fork(void);

3.脱离控制终端、登录会话和进程组。开发人员如果要摆脱它们,不受它们的影响,一般使用setsid()设置新会话的领头进程,并与原来的登录会话和进程组脱离。

4.禁止进程重新打开控制终端。

5.关闭打开的文件描述符,并重定向标准输入、标准输出和标准错误输出的文件描述符。进程从创建它的父进程那里继承了打开的文件描述符。如果不关闭,将会浪费系统资源,引起无法预料的错误。关闭三者的代码如下:
for (fd = 0, fdtablesize = getdtablesize();
fd < fdtablesize; fd++)
close(fd);

6.改变工作目录到根目录或特定目录进程活动时,其工作目录所在的文件系统不能卸下

7.处理SIGCHLD信号。SIGCHLD信号是子进程结束时,向内核发送的信号。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。因此需要对SIGCHLD信号做出处理,回收僵尸进程的资源,避免造成不必要的资源浪费。可以用如下语句:
signal(SIGCHLD,(void *)reap_status);
  捕捉信号SIGCHLD,用下面的函数进行处理:
void reap_status()
{ int pid;

….

}

程序:

init.c test.c

实验内容及步骤

守护进程实例包括两部分:主程序test.c和初始化程序init.c。主程序每隔一分钟向/tmp目录中的日志test.log报告运行状态。初始化程序中的init_daemon函数负责生成守护进程。读者可以利用init_daemon函数生成自己的守护进程。

1. init.c
#include < unistd.h >
#include < signal.h >
#include < sys/param.h >
#include < sys/types.h >
#include < sys/stat.h >

#include

void init_daemon(void)
{
int pid;
int i;

if(pid=fork())
exit(0);//是父进程,结束父进程
else if(pid< 0)
exit(1);//fork失败,退出
//是第一子进程,后台继续执行

setsid();//第一子进程成为新的会话组长和进程组长
//并与控制终端分离
if(pid=fork())
exit(0);//是第一子进程,结束第一子进程
else if(pid< 0)
exit(1);//fork失败,退出
//是第二子进程,继续
//第二子进程不再是会话组长

for(i=0;i< NOFILE;++i)//关闭打开的文件描述符
close(i);
chdir("/tmp");//改变工作目录到/tmp
umask(0);//重设文件创建掩模
return;
}
2. test.c

#include < stdio.h >

#include < time.h >

void init_daemon(void);//守护进程初始化函数

intmain() {

FILE *fp;

time_t t;

init_daemon();//初始化为Daemon

while(1)//每隔一分钟向test.log报告运行状态
{
sleep(60);//
睡眠一分钟
if((fp=fopen("test.log","a")) >=0)
{
t=time(0);
fprintf(fp,"I'm here at %sn",asctime(localtime(&t)) );
fclose(fp);
}

}

}

编译: [root@vm root]#gcc –g –o test init.c test.c
执行: [root@vm root]#./test
查看进程: [root@vm root]#ps –ef
从输出可以发现test守护进程的各种特性满足上面的要求,这个问题掌握了,会在嵌入式开发中如虎添翼,加油吧。。。。。。

Baidu
map