当前位置: > 华清远见教育科技集团 > 嵌入式学习 > 讲师博文 > 关于守护进程
关于守护进程
时间:2016-12-14作者:华清远见

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<stdio.h>
        #include<stdlib.h>
        #include<unistd.h>
        #include<sys/types.h>

        int main()
        {
                int fd,fdtablesize;
                pid_t pid;
                if(-1 ==(pid = fork()))
                {
                        perror("fork");
                        exit(1);
                }
                if(pid > 0)
                {
              &nbnbsp;         exit(0);
                }
                else
                {
                        setsid();    //使子进程成为新的会话组组长
                        chdir("/");     //改变工作目录为根目录
                        umask(0);    //重设文件权限掩码
                        fdtablesize = getdtablesize();  //得到文件描述符表的大小
                        for(fd = 0;fd < fdtablesize;fd ++)  //关闭多余的文件描述符
                        {
                                close(fd);
                        }
                        //while(1);    //这是为了不让父进程退出,可以查看到守护进程。
                }
                return 0;
        }

发表评论
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)