作者:庄老师,华清远见嵌入式学院讲师。 1、守护进程的意义: 在linux中,每一个系统与用户进行交流的界面称为终端。从该终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。 守护进程能够突破这种限制,它从开始运行,直到整个系统关闭才会退出。如果想让某个进程不会因为用户或终端的变化而受到影响,就必须把这个进程变成一个守护进程。 2、守护进程的编写步骤: (1)创建子进程,父进程退出。 第一步完成以后,子进程就在形式上做到了与控制终端的脱离。由于父进程先于子进程退出,子进程变成孤儿进程。 (这里说的形式上是指子进程交给init,即1号进程收养,但还是原来的会话组,组号不变。) 代码段 pid = fork();
if(pid > 0)
{
exit(0);
} (2)在子进程中创建新会话。 进程组是一个或多个进程的集合,进程组由进程组ID来唯一标识。每个进程组都有一个组长进程,进程组ID就是组长进程的进程号。会话期是一个或多个进程组的集合。 在子进程中创建新会话需要用到setsid函数,setsid函数用于创建一个新的会话,并使得当前进程成为新会话组的组长。(即孤儿进程成为新会话组的组长)若当前进程是组长,则出错。setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。 函数原型: pid_t setsid(void); (3)改变当前目录为根目录。 (默认工作目录是在根目录下。) 通常做法是让"/'(只有root才可创建文件)或“/tmp”(所有用户都可以操作)作为守护进程的当前工作目录。因为这两个目录不可被卸载。 在进程运行过程中,当前目录所在的文件系统是不能卸载的。改变工作目录要用到函数chdir。 函数原型: int chdir(const char *path); (4)重设文件权限掩码。 文件权限掩码是指文件权限中被屏蔽掉的对应位。把文件权限掩码设置为0,可以增加该守护进程的灵活性。 设置文件权限掩码的函数式:umask 函数原型: mode_t umask(mode_t mask); (5)关闭文件描述符。 新建的子进程会从父进程那里继承所有已经打开的文件。在创建新的会话后,守护进程已经脱离任何控制终端,应当关闭用不到的文件。如果守护进程需要操作文件描述符,再打开。 得到文件描述符表的大小用到函数:getdtablesize(),d表示descriptor文件描述符。 函数原型: int getdtablesize(void); 守护进程创建样例: #include
#include
#include
#include
int main()
{
int fd,fdtablesize;
pid_t pid;
if(-1 ==(pid = fork()))
{
perror("fork");
exit(1);
}
if(pid > 0)
{
exit(0);
}
else
{
setsid(); //使子进程成为新的会话组组长
chdir("/"); //改变工作目录为根目录
umask(0); //重设文件权限掩码
fdtablesize = getdtablesize(); //得到文件描述符表的大小
for(fd = 0;fd < fdtablesize;fd ++) //关闭多余的文件描述符
{
close(fd);
}
//while(1); //这是为了不让父进程退出,可以查看到守护进程。
}
return 0;
}
[ 本帖最后由 farsight2009 于 2013-10-29 10:12 编辑 ]
|