守护进程

守护进程

(deamon)是一种特殊的进程,类似于windows下的服务,是一种在后台运行的服务进程,独立于控制终端,一般由系统启动时,引导启动,随着系统的关闭而关闭,不会随着用户的登录或者注销的影响

守护进程的运行方式

①独立运行的守护进程:独立运行的守护进程由 init 脚本负责管理,所有独立运行的守护进程的脚本在/etc/rc.d/init.d/目录下。
②由 xinetd 管理的守护进程:可以把xinetd看作一个管理启动服务的管理服务器,它决定把一个客户请求交给那个程序处理,然后启动相应的守护程序。

创建守护进程

要想创建守护进程,我们需要先知道以下的概念。
- 进程组:进程组是一个或多个进程的集合,通常它们与一组作业相关联,可以接受来自同一终端的各种信号。每个进程组有一个领头进程,叫做进程组组长。pid_t getpgrp(void);该函数可以获取进程组的PID(即进程组组长的PID).int setpgid(pid_t pid, pid_t pgid);调用该函数该函数可以参加一个现存的组或者创建一个新进程组。需要注意的是,当父进程fork()出子进程的时候,系统会自动将子进程所在的进程组的组长设置为父进程。
- 会话:会话由多个进程组组成

创建会话的进程将会成为新进程组的组长
注意,创建会话的进程不能是进程组组长。pid_t getsid(pid_t pid);获取进程所属的会话ID。pid_t setsid(void);创建一个会话。

创建守护进程模型:

  1. fork()创建子进程,父进程退出。(子进程成为孤儿进程,不再由父进程控制子进程的生死)
  2. 子进程创建新会话。(成为会话组长,和进程组组长,脱离控制终端)
  3. 改变当前工作目录 chdir 。(建议步骤,为守护进程设置新的工作目录)
  4. 重设文件掩码 umask 。(建议步骤,增加程序的灵活性,守护进程和父进程将同同一文件,拥有不同的权限。umask(0)可以将所有权限给予守护进程。文件的最大权限为0777,其中umask的参数填写你要扣除的权限.0777即 (-rwxrwxrwx,文件拥有者的权限,同一用户组的权限,不同用户组的权限)r=4,w=2,x=1)
  5. 关闭文件描述符close(建议步骤,关闭从父进程那里继承来的文件描述符(标准输入,标准输出,标准错误))
  6. 守护进程的工作 sigaction捕捉信号(守护进程经常会使用信号进行通信,通过信号控制守护进程的退出,也可以使用signal,注意,signal并不是POSIX标准,机器不同,实现有可能不同)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>

void dowork(int no)
{
    //得到当前系统时间
    time_t curtime;
    time(&curtime);
    //格式化
    char* pt = ctime(&curtime);
    //将时间写入
    int fd = open("/home/tarena/a.txt",O_CREAT | O_WRONLY | O_APPEND,0664);
    write(fd,pt,strlen(pt)+1);
    close(fd);

}
int main(int argc,char* argv[])
{
    pid_t pid;
    /*1.生成新进程,关闭父进程*/
    pid=fork();
    if(pid == 0)
    {
        /*2.子进程创建会话*/
        setsid();
        /*3.改变当前工作目录*/
        chdir("/");
        /*4.重设文件掩码*/
        umask(0);
        /*5.关闭文件描述符*/
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        /*6.守护进程工作,定时写入文件*/
        //注册信号捕捉,signal
        struct sigaction act;
        //回调
        act.sa_handler = dowork;
        act.sa_flags = 0;
        sigemptyset(&act.sa_mask);
        sigaction(SIGALRM,&act,NULL);
        //创建定时器
        struct itimerval val;
        //第一次触发时间
        val.it_value.tv_usec = 0;
        val.it_value.tv_sec = 2;
        //循环周期
        val.it_interval.tv_usec = 0;
        val.it_interval.tv_sec = 1;
        while(1)
        {
        /*定时器到时会发送SIGALRM*/
            setitimer(ITIMER_REAL,&val,NULL);
        }
    }
    else if (pid < 0)
    {
        perror("error is :");
        return -1;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值