Linux之————守护进程与crond定时任务

一. 守护进程

守护进程又称为精灵(Daemon)进程,顾名思义,守护是一直会存在的,它是运行在后台的一种特殊的进程,独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。比如当Linux系统启动的时候会启动一些系统服务进程,因为这些进程没有控制终端因此不能直接和用户进行交互,它的生命周期随系统,而不是像用户登录或者运行程序才开始启动的而进程运行完毕或者用户注销后就终止,这种进程就称之为守护进程或者精灵进程

可以在终端下查看系统中的守护进程,这些进程通常以精灵的单词Daemon的首字母d结尾:

从上面可以看到,大多数进程的进程ID号、进程组ID和会话ID都是同一个ID号,而其控制终端TTY是没有的,因此,守护进程有如下特点:

  1. 守护进程自成进程组并且自成会话,也就是守护进程所在的进程组和会话中只有自身一个进程;
  2. 守护进程不与终端设备关联;

二. 创建守护进程

我们可以自己利用守护进程的特点创建一个守护进程,而使用到的函数是setsid函数:

该函数的参数为空,返回值是pid_t也就是调用该函数的进程ID号;

setsid函数调用有如下三个特点:

  1. 新创建出一个会话并且调用函数进程为会话首进程,会话ID为进程ID;
  2. 新创建出一个进程组并且调用函数进程为进程组的组长进程,进程组ID为进程ID;
  3. 若调用函数进程和一个控制终端关联,则失去这个终端,这个终端仍然会存在并且可以读写,但只是一个文件而不再是一个控制终端;

这里需要强调的是,在调用setsid之前必须保证调用函数进程不是组长进程,这样的话,可以考虑用fork来创建出子进程,让子进程来调用setsid,因为在同一个进程组中子进程之前还有进程,而组长进程是该组的第一个进程,这样就可以确定子进程不是组长进程了。

创建守护进程一般有如下几个步骤:

  1. 调用umask将文件模式创建屏蔽字设置为0,以确保党进程想要生成文件时不受系统权限的控制;
  2. 调用fork创建出子进程,以确保子进程不是组长进程,同时使父进程退出只保留子进程;
  3. 调用setsid函数,该函数创建成功会新建一个会话和一个进程组,该进程组ID和会话ID都是子进程的ID,同时使子进程失去其原本链接的控制终端(再次fork,使当前子进程退出,因为当前子进程是话首进程可能之后还会打开控制终端,而再次fork出的子进程不是话首进程,确保之后不会再次打开控制终端);
  4. 将当前用户目录更改为根目录,使进程工作目录稳定;
  5. 关掉不需要的文件描述符;
  6. 其他(忽略SIGCHILD信号);

程序设计:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

void my_daemon()
{
    umask(0);//设置文件创建屏蔽字为0

    pid_t pid;
    pid = fork();//创建出子进程
    if(pid < 0)
    {   
        printf("first fork failed...\n");
        perror("fork");
    }   
    else if(pid > 0)//father   父进程退出
    {   
        printf("father process out...pid: %u\n", getpid());
        exit(0);
    }   

    //child   子进程
    printf("child process...pid: %u\n", getpid());

    if((pid = setsid()) < 0)//调用setsid函数创建守护进程
        perror("setsid");
    else
        printf("create daemon process success...pid: %u\n", getpid());

    if((pid = fork()) < 0)//再次fork并使父进程退出,确保子进程不是话首进程不会再打开TTY设备
    {   
        printf("second fork failed...\n");
        perror("fork");
    }   
    else if(pid > 0)//father   父进程退出
    {   
        printf("last child as father process out...pid: %u\n", getpid());
        exit(1);
    }

    if(chdir("/") < 0)//将工作目录更改为根目录
    {
        printf("change dir failed...\n");
        perror("chdir");
    }

    printf("signal: %u\n", signal(SIGCHLD, SIG_IGN));

    if(close(0) < 0)//关掉标准输入
        printf("close stdin failed...\n");
    if(close(2) < 0)//关掉标准输出
        printf("close stderr failed...\n");
    if(close(1) < 0)//关掉标准错误
        printf("close stdout failed...\n");
}

int main()
{
    my_daemon();
    while(1);
    return 0;
}

运行程序:

程序运行结果到“signal:0”输出就结束了,但这里并不是死循环,因为第一次fork使父进程退出,此时shell认为当前作业已经完成,将把bash放到前台运行,但这时候daemon进程虽然调用setsid失去了控制终端,但还是能够进行读写,因此还是会打印出信息,只是不再作为一个控制终端了,用jobs命令来查看后台也查看不到,可用下面命令来查看:

查看结果发现有一个自己写的daemon进程,可以看到其进程组ID和会话ID就是前面运行程序结果中调用setsid函数后来再次fork又退出的进程,而其TTY一项并没有关联,因此daemon是一个守护进程。

-------------------------------------------------------------------------------------------

在上面罗列出的系统的守护进程中,有一个crond的守护进程,这个进程的作用就是定期执行任务或等待处理某些任务,在目录/etc下就可以查看有关的文件:

cron.allow里面存放用户名,用来标识是否允许用户拥有自己的cron定时任务,一开始是没有这个文件的,可以由超级用户添加;

cron.deny里面则存放了禁止用户使用cron守护进程;

打开crontab文件:

每个用户都可以有自己的crontab文件,而文件内容的格式则如上图:每一个*号的位置都是时间点,而后面则是定时要执行的任务;

*表示每分钟(小时、周、月...)都要执行;

*/n表示每隔n分钟(小时、周...)执行;

t1--t2表示在t1--t2时间段里都要执行;

t1,t2,t3表示分别在t1,t2,t3时间执行;

crontab -e 可以编辑用户crontab文件内容,若没有指定用户则为当前用户;

crontab -l 显示用户的crontab文件内容;

crontab -r 删除用户的crontab文件;

crontab -u 设定某个用户的cron服务,一般是超级用户;

另外:

service crond start   启动cron服务;

service crond stop    停止cron服务;

service crond restart  重启cron服务;

service crond status  查看当前cron状态

用户的crontab文件存放在目录/var/spool/cron下,文件名就是用户名;

比如在root的crontab文件中写入命令:

*/1 * * * * echo You should drink some water... >> test.txt

则重新启动cron服务并用tail -f 来查看:

如上所示,每隔一分钟就向test.txt文件追加一句话,这样就完成了用户自己的一个定时任务。

《完》

时间: 2024-10-07 11:25:55

Linux之————守护进程与crond定时任务的相关文章

深入理解Linux操作系统守护进程的意义

Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程(daemons)来执行的.守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止.linux系统有很多守护进程,大多数服务器都是用守护进程实现的.同时,守护进程完成许多系统任务,比如,作业规划进程crond.打印进程lqd等.有些书籍和资料也把

linux C守护进程编写

linux编程-守护进程编写 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待 处理某些发生的事件.守护进程是一种很有用的进程. Linux的大多数服务器就是用守护进程实现的.比如,Internet服务器inetd,Web服务器httpd等. 同时,守护进程完成许多系统任务.比如,作业规划进程crond,打印进程lpd等. 守护进程的编程本身并不复杂,复杂的是各种版本的Unix的实现机制不尽相同, 造成不同 Unix环境下守护进程的编程规则并不一

linux 创建守护进程的相关知识

linux 创建守护进程的相关知识 http://www.114390.com/article/46410.htm linux 创建守护进程的相关知识,这篇文章主要介绍了linux 创建守护进程的相关知识,需要的朋友可以参考下 关键字:linux.守护进程 创建子进程,父进程退出 这是编写守护进程的第一步.由于守护进程是脱离控制终端的,因此,完成第一步后就会在Shell终端里造成一程序已经运行完毕的假象.之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到

asp.net core2.0 部署centos7/linux系统 --守护进程supervisor(二)

原文:asp.net core2.0 部署centos7/linux系统 --守护进程supervisor(二) 续上一篇文章:asp.net core2.0 部署centos7/linux系统 --安装部署(一),遗留的问题而来,对程序添加守护进程,使网站可以持续化的运行起来. ? 1.介绍supervisor ?? ?Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,

Linux:守护进程

守护进程也称精灵进程(Daemon): 是运行在后台的一种特殊进程.他独立与控制终端并且周期性的执行某种任务或者处理某些发生的事情.守护进程是一种很有用的进程,在操作系统中,维护系统各种设施的进程. 在Linux中,大多数服务器就是守护进程实现的:比如:Internet服务器inetd,Web服务器httpd 在上一篇博文例行性工作中.crond就是守护进程进行的任务. 系统服务进程不受用户注销登录的影响,只随系统关闭而关闭. 用ps axj命令查看系统中的进程.参数a表示不仅列当前用户的进程,

linux的守护进程init.d和xinetd.d

Linux 服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程来执行的.守护进程是生存期长的一种进程.它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件.他们常常在系统引导装入时启动,在系统关闭时终止.linux系统有很多守护进程,大多数服务器都是用守护进程实现的.同时,守护进程完成许多系统任务,比如,作 业规划进程crond.打印进程lqd等.有些书籍和资料也把守护进程称作:

linux下守护进程的创建

最近在学习linux c编程 看到了守护进程的创建,感觉很好玩, 测试环境ubuntu 15.04 下面贴出测试代码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/param.h> #include <sys/stat.h> #include <time.h> #include <

编写Linux/Unix守护进程

原文: http://www.cnblogs.com/haimingwey/archive/2012/04/25/2470190.html 守护进程在Linux/Unix系统中有着广泛的应用.有时,开发人员也想把自己的程序变成守护进程.在创建一个守护进程的时候,要接触到子进程.进程组.会晤期.信号机制.文件.目录和控制终端等多个概念.因此守护进程还是比较复杂的,在这里详细地讨论Linux/Unix的守护进程的编写,总结出八条经验,并给出应用范例. 编程要点 1.屏蔽一些有关控制终端操作的信号.防

linux创建守护进程

守护进程deamon 是一个后台进程,无需用户输入就能运行,用来在系统后台提供某种服务. 常见的守护进程有Wbe服务器.邮件服务器以及数据库服务器等等.守护进程不能控制终端,所以任何的输入和输出都需要做特殊处理. 创建守护进程的过程并不复杂,首先执行fork(),将父进程退出. 一个守护进程是从shell脚本或者命令启动,守护进程和应用程序不同的地方是守护进程不是交互式的,它在后台运行,不控制终端. 守护进程既不需要从标准输入设备读入信息,也不需要从标准输出设备输出信息. 下一步是在子进程中调用