Linux下守护进程

1 守护进程的概念
  守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着。这种进程有一个名称叫守护进程(Daemon)。Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond等。
  使用ps axj命令查看系统中的进程。参数a表示不仅列当前用户的进程,也列出所有其他用户的进程,参数x表示不仅列有控制终端的进程,也列出所有无控制终端的进程,参数j表列出与作业控制相关的信息。TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程。
2 创建守护进程
  创建守护进程步主要是调用setsid函数创建一个新的Session,并成为Session Leader。
  1) 相关函数

#include <unistd.h>
pid_t setid(void)

  函数调用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1。注意,调
用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不是进程组的Leader,先fork再调用setsid就行了。fork创建的子进程和父进程在同一个进程组中,进程组的Leader必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子进程中调用setsid就行了。调用该函数的结果:
  1> 创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。
  2> 创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。
  3> 如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进
程。所谓失去控制终端是指,原来的控制终端仍然是打开的,仍然可以读写,但只是一个普
通的打开文件而不是控制终端了。
  2) 创建步骤
  1> 调用umask将文件模式创建屏蔽字设置为0.
  2> 调用fork,父进程退出(exit)。原因:1)如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使得shell认为该命令已经执行完毕。 2)保证子进程不是一个进程组的组长进程。
  3> 调用setsid创建一个新会话。setsid会导致:1)调用进程成为新会话的首进程。2)调用进程成为⼀个进程组的组长进程 。 3)调用进程没有控制终端。(再次fork一次,保证daemon进程,之后不会打开tty设备)。
  4> 将当前工作目录更改为根目录。
  5> 关闭不在需要的文件描述符。
  6> 其他:忽略SIGCHLD信号。
3 程序代码

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
void creat_daemon(void)
{
    int i;
    int fd0;
    pid_t pid;
    struct sigaction sa;
    umask(0); 
    if( (pid = fork()) < 0 )
    {
        perror("fork\n");
        return;
    }
    else if (pid != 0)
        exit(0);

    setsid(); 

    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    if(sigaction(SIGCHLD, &sa, NULL ) < 0 )
        return;

    if( (pid = fork())<0)
    {
        printf("fork\n");
        return;
    }
    else if( pid != 0)
        exit(0);

    if( chdir("/") < 0 )
    {
        printf("chdir\n");
        return;
    }
    close(0);
    fd0 = open("/dev/null", O_RDWR);
    dup2(fd0, 1);
    dup2(fd0, 2);
}
int main()
{
    creat_daemon();
    while(1)
    {
        sleep(1);
    }
}

  结果如下图:
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值