守护进程

守护进程
1.让进程在后台执行。方法是调用fork产生一个子进程,然后使得父进程退出。

2.调用setsid创建一个新会话。控制终端,登录会话和进程组通常是从父进程继承下来的,守护进程要摆脱它们,不受它们影响,其方法是调用setsid使进程成为一个会话组长。

    Linux中的进程与控制终端,登录会话和进程组之间的关系:进程属于一个进程组,进程组号(GID)就是进程组长的进程号(PID)。登录会话可以包含多个进程组。这些进程组共享一个控制终端。这个控制终端通常是创建进程的登录终端。控制端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:setsid();

说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。

如果,调用setsid的进程不是一个进程组的组长,此函数创建一个新的会话期。

(1)此进程变成该对话期的首进程

(2)此进程变成一个新进程组的组长进程。

(3)此进程没有控制终端,如果在调用setsid前,该进程有控制终端,那么与该终端的联系被解除。如果该进程是一个进程组的组长,此函数返回错误。

(4)为了保证这一点,我们先调用fork()然后exit(),此时只有子进程在运行。


编写守护进程的一般步骤步骤:

(1)在父进程中执行fork并exit退出;

(2)在子进程中调用setsid函数创建新的会话;

(3)在子进程中调用chdir函数,让根目录 ”/” 成为子进程的工作目录;

(4)在子进程中调用umask函数,设置进程的umask为0;

(5)在子进程中关闭任何不需要的文件描述符


#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <stdlib.h>

int init_daemon(void)
{
    int pid;
    int i;
    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTSTP, SIG_IGN);
    signal(SIGHUP, SIG_IGN);
    pid = fork();
    if(pid > 0)
        exit(0);
    else if(pid == -1)
        return -1;

    setsid();

    pid = fork();
    if(pid > 0)
        exit(1);
    else if(pid == -1)
        return -1;

    for(i = 0; i < NOFILE; close(i++))
        ;
    chdir("/");

    umask(0);

    signal(SIGCHLD, SIG_IGN);

    return 0;
}

int main(void)
{
    time_t now;
    init_daemon();
    while(1)
    {
        sleep(8);
        time(&now);

        printf("系统时间:\t%s\t\t\t\n", ctime(&now));
    }

    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值