Linux守护进程的实现

对于守护进程来说,刚开始我并不是十分的理解,只知道它是一个后台进程,可以脱离终端执行相应的操作。对于实现过程,刚开始并没有弄清楚,今天我将守护进程的实现过程研究了一遍,实现代码在下面贴出。

守护进程的介绍参考:http://blog.csdn.net/zhengqijun_/article/details/52842519

Linux守护进程的实现过程

/*****************************************************
copyright (C), 2014-2015, Lighting Studio. Co.,     Ltd. 
File name:Linux守护进程
Author:zhengqijun   Version:1.0    Date: 2016/11/20
Description:守护进程的实现 
*****************************************************/

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

void init_daemon(void)
{
    int i;
    pid_t pid;

    if((pid = fork()) > 0)    //结束父进程,退出
    {
        printf("This is father exit!\n");
        exit(0);
    }
    else if(pid < 0)    //fork出错
    {
        printf("fork is error!\n");
        exit(1);
    }
    else    //第一子进程继续运行
    {
        printf("This is son working!\n");
        
        setsid();    //第一子进程成为新的会话组长和进程组长,并与控制终端分离
        
        if((pid = fork()) > 0)    //结束第一子进程,退出
        {
            exit(0);
        }
        else if(pid < 0)    //fork出错
        {
            printf("fork is error!\n");
            exit(1);
        }
        else    //第二子进程继续运行
        {
            printf("pid is %d\n", getpid());    //打印守护进程的id号

            for(i = 0; i < NOFILE; ++i)    //关闭打开的文件描述符,包括标准输入、标准输出和标准错误输出
            {
                close(i);
            }
            chdir("/tmp");    //将工作目录改为/tmp
            umask(0);    //重设文档创建掩模

            return ;
        }
    }
}

int main()
{
    FILE *fp;
    time_t t;

    init_daemon();    //守护进程初始化

    while(1)
    {
        /* 我将守护进程打印的信息储存到daemon.txt文件中进行保存,这样也方便观察守护进程是否运行 */
        sleep(5);        //每过5s,打开一次文件,写入数据。
        if((fp = fopen("daemon.txt", "a")) >= 0)
        {
            t = time(0);
            fprintf(fp, "I am here at %s", asctime(localtime(&t)));
            fclose(fp);
        }
    }

    return 0;
}

编译成功后,运行的结果如下所示:

[root@localhost 1120]# vim daemon.c
[root@localhost 1120]# gcc -o daemon daemon.c -Wall
[root@localhost 1120]# ./daemon 
This is son working!
pid is 1665
This is father exit!
文件daemon.txt中保存的数据如下图所示



通过结果可以看出守护进程一直在后台运行,并且每过5s就会向daemon.txt文件中写入一次数据。如果系统不关闭,那么守护进程将一直运行。当然也可以通过kill语句来杀死守护进程。

我相信对初学者来说,肯定会问为什么会调用两次fork语句呢?

我觉得第一次调用fork函数,为避免挂起,控制终端将守护进程放入后台执行,然后调用setsid()函数脱离控制终端和进程组,使该进程成为会话组长,并与原来的登录会话和进程组脱离。此时进程已经成为无终端的会话组长,但它可以重新申请打开一个控制终端。为了避免这种情况,可以通过使进程不再成为会话组长来禁止进程重新打开控制终端,这就需要第二次调用fork()函数。父进程(会话组长)退出,子进程继续执行,并不再拥有打开控制终端的能力。在正在执行的进程中调用INIT_DAEMON后,进程将成为守护进程,脱离控制终端进入后台执行。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值