守护进程知识及示例

守护进程(Daemon进程)
与终端无关的进程,运行在后台,生存期较长,系统关闭时终止或可以通过命令终止或通过ps找到进程用kill杀死,有的以d结尾
终端是人与电脑交互的界面:

这里写图片描述
要以管理员身份启动:service httpd start
查看命令:ps -ef|grep httpd
关闭:service httpd stop

这里写图片描述
这里写图片描述
这里写图片描述
用命令ps -axj查看常用的守护进程:
这里写图片描述
这里写图片描述
从结果可以看出守护进程没有控制终端,其终端名设置为?,终端前台进程组ID设置为-1,init进程ID为1。系统进程依赖于操作系统实现,父进程ID为0的各进程通常是内核进程,它们作为系统自举的一部分而启动。内核进程以超级用户特权运行,无控制终端,无命令行。大多数守护进程的父进程是init进程。

会话:打开一个终端,就建立了会话。关闭终端就关闭了会话。比如:两个人打电话就建立了会话,挂掉电话就关闭了会话。一般以整个会话运行起来的第一个进程的id命名会话(一般为shell)。
进程组:一个进程组里面有一个或多个进程。一般以组长进程id命名进程组。比如:ls为一个进程组,ls即为组长也为组员,ls命令结束进程组也结束。
会话包括一个或多个进程组,一个进程组包括一个或多个进程。
这里写图片描述
获得会话id:getsid();
获得进程组id:getpgid();
获得进程id:getpid();
参数传0,表示当前会话或进程。

守护进程的创建流程:
1.fork();创建子进程,退出父进程。只有组员才能创建新会话。
2.setsid();创建新会话,进程变成会话首进程,组长。
3.chdir();将当前工作目录更改为根目录。进程活动时,其工作目录所在的文件系统不能卸下。一般需要将工作目录改变到根目录。
4.调用umask将文件模式创建屏蔽字设置为0。因为进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:调用umask(0)。
5.close();进程从父进程那里继承了打开的文件描述符。如不关闭,将会浪费系统资源,造成进程所在的文件系统无法卸下以及引起无法预料的错误。

示例
实现一个简单的守护进程,获取本地时间,用mytest.log记录并测试

#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <unistd.h>

int main()
{
    pid_t pid=fork();
    if(pid!=0)
    {
        exit(0);
    }
    setsid();

    pid=fork();
    if(pid!=0)
    {
        exit(0);
    }

    chdir("/");

    umask(0);

    int i=0;
    for(; i<getdtablesize(); i++)
    {
        close(i);
    }
///////////////////////////////////////////////////////////////
//守护程序写完,下面是要做什么事
//////////////////////////////////////////////////////////////
    while(1)
    {
        FILE *fp=fopen("/tmp/mytest.log","a");
        assert(fp != NULL);

        time_t t;
        time(&t);
        fprintf(fp,"time is:%s", localtime(&t));
        fclose(fp);
        sleep(5);
    }
}

测试
这里写图片描述
kill守护进程
这里写图片描述

拷贝文件到/etc/init.d底下,可以使用service daemond start启动自己写的守护进程

猜你喜欢

转载自blog.csdn.net/qq_34501940/article/details/51221628