Linux--守护进程

1 什么是守护进程

1.守护进程:在后台运行,且不受终端控制的一种进程。
2.通过ps axj | more指令可以查看到Linux下的守护进程

[root@localhost 进程组]# ps axj | more
PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     1     1     1 ?           -1 Ss       0   0:03 /sbin/init
    0     2     0     0 ?           -1 S        0   0:00 [kthreadd]
    2     3     0     0 ?           -1 S        0   0:00 [migration/0]
    2     4     0     0 ?           -1 S        0   0:02 [ksoftirqd/0]
    2     5     0     0 ?           -1 S        0   0:00 [stopper/0]
    2     6     0     0 ?           -1 S        0   0:41 [watchdog/0]
    2     7     0     0 ?           -1 S        0   0:37 [events/0]
    2     8     0     0 ?           -1 S        0   0:00 [events/0]
    2     9     0     0 ?           -1 S        0   0:00 [events_long/0]
    2    10     0     0 ?           -1 S        0   0:00 [events_power_ef]
    2    11     0     0 ?           -1 S        0   0:00 [cgroup]
    2    12     0     0 ?           -1 S        0   0:00 [khelper]

可以看到:守护进程的TPGID为-1,也就是TPGID为-1的为守护进程

2 创建守护进程的流程

1.创建子进程,终止父进程

因为守护进程脱离终端的控制,一方面因为让父进程退出,就会使得当前终端可以执行其它的指令,而之后其它的操作都让子进程去执行,让子进程已一种僵尸状态来执行,就可以达到脱离终端的目的。另一方面,需要创建新的会话,而创建会话的进程不能是组长进程,让父进程创建一个子进程,那么子进程一定不是组长进程。

2.子进程创建会话

因为子进程继承了父进程的一些信息,包括会话相关的消息,子进程必须要脱离父进程所在的会话,必须创建新的会话,让子进程变为新会话的话首进程

3.屏蔽SIGCHLD信号

为了防止僵尸进程的出现

4.改变当前工作目录

因为子进程以父进程为模板,那么子进程就会和父进程处在同一个工作目录下,所以需要改变子进程的工作目录

5.重定向文件描述符

因为子进程是以父进程为模板,那么子进程就有和父进程一样的文件描述符表,父进程打开的文件,子进程也能操作,所以需要将文件描述符重定向,重定向至”/dev/null/”,这个目录相当于一个垃圾桶

6.重建文件创建掩码umask

因为创建文件时,文件创建掩码会屏蔽掉一些权限对应的位,所以需要重建文件创建掩码

3 相关代码

#include                                                                                                                       
#include 
#include 
#include 
#include 
#include 
#include 

void MyDaemon()
{
    //7.屏蔽umask
    umask(0);

    //1.创建一个子进程
    pid_t pid = fork();
    if(pid < 0)
    {
        perror("fork");
    }
    else if(pid > 0)
    {
        //2.让父进程退出
        exit(0);
    }
    //3.子进程调用setsid,创建一个新的会话,
    pid_t ret = setsid();
    if(ret < 0)
    {
        perror("setsid");
    }
    //4.忽略掉SIGCHLD信号,忽略SIGHUP信号
    signal(SIGCHLD,SIG_IGN);
    signal(SIGHUP,SIG_IGN);

    //5.修改工作目录为“/”  
    if(chdir("/") < 0)
    {
        perror("chdir");
    }

    //6.重定向文件描述符
    int fd = open("/dev/null",O_RDWR);                                                                                                  
    dup2(fd,0);
    dup2(fd,1);

}

int main()
{
    MyDaemon();   //调用该函数之后就会使得main进程变为守护进程
    while(1)
    {
        sleep(1);
    }
    return 0;
}      

​运行结果:(可以看到当前进程mydaemon的TPGID为-1,说明为守护进程)

[root@localhost 进程组]# ps axj | head -n 1 && ps axj | grep mydaemon | grep -v  grep
PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1 28482 28482 28482 ?           -1 Ss       0   0:00 ./mydaemon

4 创建守护进程的另外两种方法

1.通过daemon函数
(1)相关参数

#include 
int daemon(int nochdir, int noclose);

//nochdir为0表示将工作目录变为"/"
//noclose为0表示将文件描述符重定向至"/dev/null"

(2)代码:

#include 
#include 

int main()
{
    daemon(0,0);                                                                                                                        
    while(1)
    {   
        sleep(1);
    }   
    return 0;
}

(3)运行结果:(可以看到进程mydaemon2变为守护进程)

[root@localhost 进程组]# ps axj |head -n 1 && ps axj | grep mydaemon2 | grep -v grep
PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1 29063 29063 29063 ?           -1 Ss       0   0:00 ./mydaemon2

2.通过nohup指令(该指令与编程语言无关,适用任意一种语言)
(1)nohup 后面加上进程名 再加上&
(2)使用:

  • 例如对于下面进程:
#include 
#include 

int main()
{
    int i = 0;
    for(;i<10;++i)
    {   
        printf("%d\n",i);
        sleep(1);
    }   
    return 0;                                                                                                                           
}

将其变为守护进程:

[root@localhost 进程组]# nohup ./mydaemon3 &
[2] 29367

此时会在当前目录下生成一个nohup.out文件,但是显示下面这句话,表示权限不够,也就是没有可执行权限

[root@localhost 进程组]# nohup: ignoring input and appending output to `nohup.out'

​通过chmod +x可以给某个文件加上可执行权限,此时运行结果如下:(可以看到mydaemon3进程的运行结果显示在nohup.out文件里)

[root@localhost 进程组]# chmod +x nohup.out
[2]+  Done                    nohup ./mydaemon3
[root@localhost 进程组]# cat nohup.out
0
1
2
3
4
5
6
7
8
9

你可能感兴趣的:(linux)