crond 与 守护进程


一、 crond  (定时任务管理)

  1、crond 是linux用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond命令每分钟会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。而linux任务调度的工作主要分为以下两类: 
        1)系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存 
        2)个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置 

    2、crontab    // 让使用者在固定时间或固定间隔执行程式
(1)使用方式 :   crontab -l|-r|-e|-i [username]

(2)说明 : 
     usename :指设定指定 user 的时程表(前提:必须要有其权限才能够指定他人的时程表)。如果不使用 -u user 的话,就是表示设定自己的时程表。 
(3)参数 : 
        -e : 执行文字编辑器来设定时程表(  内定的文字编辑器是 VI  )      crontabl -e
        -r : 删除目前的时程表    crontabl -r 
        -l : 列出目前的时程表    crontabl -l

        -i : 删除时程表前给提示    crontabl -ri    

 (4)   时程表   的格式 :     f1   f2   f3   f4   f5   program 
      注:     f1 :分钟,f2 :小时,f3 :日期,f4 :月份,f5 :    ,program :要执行的程式。 

    若 f1(f2... ...) :“  *  ” ---> 每分钟(小时... ...)都要执行程式

           "    */n   "   ---->  每 n 分钟(... ...)个时间间隔执行一次

      " a, b, c,... "---> 第 a, b, c,... 分钟(... ...)要执行

(5)使用者也可以将所有的设定先存放在档案 file 中,用 crontab file 的方式来设定时程表。 
     使用方法: 用VI编辑一个文件 cronfile,然后在这个文件中输入格式良好的时程表。编辑完成后,保存并退出。

            $: crontab cronfile 

(6)使用方法:

    service crond start   启动cron服务;

    service crond stop    停止cron服务;

    service crond restart  重启cron服务;

    service crond status  查看当前cron状态


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

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

    */1 * * * * echo It's study time >> test.txt

    即,每隔一分钟打印出“It's study time”。

二、守护进程  (没有控制终端)

    守护进程,亦称为“精灵进程”。守护进程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件,即不与任何控制终端相关联。

    守护进程通常采用以d结尾的名字,表示 Daemon.


    参数a:列 当前用户的进程 + 所有其他用户的进程

    参数x:列 有 控制终端的进程 + 所有 无控制终端的进程

    参数j:列出 与 作业控制相关的信息。

        例:ps axj | grep -E 'd$'  // 查找所有 以d结尾 的进程

               

      TPGID:-1 --> 没有控制终端的进程(守护进程)

      COMMAND:[] ---> 内核进程

创建守护进程

    1. 调用 umask将文件模式创建屏蔽字设置为0。     ( umask(0); )

    2. 调用 fork,父进程退出(exit)。

        原因:1)如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使得shell认为该命令已经执行完毕。

              2)保证子进程不是一个进程组的组长进程。

    3. 调用setsid创建一个新会话。     ( setsid(); )

        setsid会导致: 1)调用进程成为新会话的首进程。

              2)调用进程成为一个进程组的组长进程 。

              3)调用进程没有控制终端。(再次fork一次,保证daemon进程,之后不会打开tty设备)

    4. 将当前工作目录更改为根目录。    (chdir)

    5. 关闭不在需要的文件描述符(输入输出错误)。

    6. 其他:忽略SIGCHLD信号。

实例:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<errno.h>

#define MAXFILE 3
void my_daemon()
{
	int i=0;
	int fd;
	struct sigaction sa;
	sa.sa_handler = SIG_IGN;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	umask(0);
	pid_t id=fork();
	if(id < 0)
	{
		perror("fork");
		exit(1);
	}
	else if(id > 0)//father
	{
		exit(0);
	}

	setsid();

	if(id < 0)
	{
		perror("fork");
		exit(1);
	}
	else if(id > 0)//father
	{
		exit(0);
	}



	if(chdir("/") < 0)
	{
		perror("chdir");
		exit(1);
	}
	for(int i=0;i<MAXFILE;i++)
	{
		close(i);
	}
	signal(SIGCHLD,SIG_IGN);
	close(fd);
}
int main()
{
	FILE *fp;
	time_t t;
	my_daemon();
	while(1)
	{
		sleep(6);
		if( (fp=fopen("./test.log", "a")) >= 0)
		{
			int i=0;
			t = time(0);
			fprintf(fp, "[%d]hello friends \n", i++);
			fclose(fp);
		 }
	}
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章