首页 > 系统相关 >Linux 守护进程

Linux 守护进程

时间:2023-11-06 14:45:14浏览次数:33  
标签:rawtime 终端 Linux 进程 ID 守护

1.进程组

  • 进程组,也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。
  • 每个进程都属于一个进程组。在 waitpid函数 和 kill函数 的参数中都曾使用到。操作系统设计的进程组的概念,是为了简化对多个进程的管理。
  • 当父进程,创建子进程的时候,默认子进程与父进程属于同一进程组。进程组ID为第一个进程ID(组长进程)。所以,组长进程标识:其进程组ID为其进程ID
  • 可以使用kill -SIGKILL -进程组ID(负进程组ID)来将整个进程组内的进程全部杀死:

 

  • 组长进程可以创建一个进程组,创建该进程组中的进程,然后终止。只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关。
  • 进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)。
  • 一个进程可以为自己或子进程设置进程组ID

2.会话

2.1 会话概念

  • 一个会话可以有一个控制终端。这通常是终端设备或伪终端设备;
  • 建立与控制终端连接的会话首进程被称为控制进程;
  • 一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组;
  • 如果一个会话有一个控制终端,则它有一个前台进程组,其它进程组为后台进程组;
  • 如果终端接口检测到断开连接,则将挂断信号发送至控制进程(会话首进程)。

2.2 创建会话注意事项

1) 调用进程不能是进程组组长,该进程变成新会话首进程(session header)

2) 该调用进程是组长进程,则出错返回

3) 该进程成为一个新进程组的组长进程

4) 需有root权限(ubuntu不需要)

5) 新会话丢弃原有的控制终端,该会话没有控制终端

6) 建立新会话时,先调用fork, 父进程终止,子进程调用setsid

3.守护进程

  守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。一般采用以d结尾的名字。

  守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。

  Linux 的大多数服务器就是用守护进程实现的。比如,Internet 服务器 inetd,Web 服务器 httpd 等

3.1 守护进程概念

  • 守护进程是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或循环等待处理某些事件的发生;它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。
  • 守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机才随之一起停止运行;
  • 守护进程一般都以root用户权限运行,因为要使用某些特殊的端口(1-1024)或者资源;
  • 守护进程的父进程一般都是init进程,因为它真正的父进程在fork出守护进程后就直接退出了,所以守护进程都是孤儿进程,由init接管;
  • 守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备stdout还是标准出错设备stderr的输出都需要特殊处理。
  • 守护进程的名称通常以d结尾,比如sshd、xinetd、crond等

3.2 守护进程模型

1) 创建子进程,父进程退出(必须)

  • 所有工作在子进程中进行形式上脱离了控制终端

2) 在子进程中创建新会话(必须)

  • setsid()函数
  • 使子进程完全独立出来,脱离控制

3) 改变当前目录为根目录(不是必须)

  • chdir()函数
  • 防止占用可卸载的文件系统
  • 也可以换成其它路径

4) 重设文件权限掩码(不是必须)

  • umask()函数
  • 防止继承的文件创建屏蔽字拒绝某些权限
  • 增加守护进程灵活性

5) 关闭文件描述符(不是必须)

  • 继承的打开文件不会用到,浪费系统资源,无法卸载

6) 开始执行守护进程核心工作(必须)

7) 守护进程退出处理程序模型

3.3 示例代码

  每隔2s获取一次系统时间, 将这个时间写入到磁盘文件:

/*
* time_t rawtime;
* time ( &rawtime  ); --- 获取时间,以秒计,从1970年1月一日起算,存于rawtime
* localtime ( &rawtime  ); //转为当地时间,tm 时间结构
* asctime() // 转为标准ASCII时间格式:
*/
void write_time(int num)
{
    time_t rawtime;
    struct tm * timeinfo;
    // 获取时间
    time(&rawtime);
#if 0
    // 转为本地时间
    timeinfo = localtime(&rawtime);
    // 转为标准ASCII时间格式
    char *cur = asctime(timeinfo);
#else
    char* cur = ctime(&rawtime);
#endif
​
    // 将得到的时间写入文件中
    int fd = open("/home/edu/timelog.txt", O_RDWR | O_CREAT | O_APPEND, 0664);
    if (fd == -1)
    {
        perror("open error");
        exit(1);
    }
    // 写文件
    int ret = write(fd, cur, strlen(cur) + 1);
    if (ret == -1)
    {
        perror("write error");
        exit(1);
    }
    // 关闭文件
    close(fd);
}
​
int main(int argc, const char* argv[])
{
    pid_t pid = fork();
    if (pid == -1)
    {
        perror("fork error");
        exit(1);
    }
​
    if (pid > 0)
    {
        // 父进程退出
        exit(1);
    }
    else if (pid == 0)
    {
        // 子进程
        // 提升为会长,同时也是新进程组的组长
        setsid();
​
        // 更改进程的执行目录
        chdir("/home/edu");
​
        // 更改掩码
        umask(0022);
​
        // 关闭文件描述符
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
​
        // 注册信号捕捉函数
        //先注册,再定时
        struct sigaction sigact;
        sigact.sa_flags = 0;
        sigemptyset(&sigact.sa_mask);
        sigact.sa_handler = write_time;
        sigaction(SIGALRM, &sigact, NULL);
​
        // 设置定时器
        struct itimerval act;
        // 定时周期
        act.it_interval.tv_sec = 2;
        act.it_interval.tv_usec = 0;
        // 设置第一次触发定时器时间
        act.it_value.tv_sec = 2;
        act.it_value.tv_usec = 0;
        // 开始计时
        setitimer(ITIMER_REAL, &act, NULL);
​
        // 防止子进程退出
        while (1);
    }
​
    return 0;
}

 

标签:rawtime,终端,Linux,进程,ID,守护
From: https://www.cnblogs.com/stux/p/17812635.html

相关文章

  • linux shell 函数,实现自动补全
    实例1:function_bigtool(){COMPREPLY=()localcur=${COMP_WORDS[COMP_CWORD]};localcom=${COMP_WORDS[COMP_CWORD-1]};case$comin'vs')COMPREPLY=($(compgen-W'checkoutdisplayremoveadd'--$cur))......
  • Perf in Linux
    PerfCommands:perfroot@f5c6cb9f45b1:/#perfusage:perf[--version][--help][OPTIONS]COMMAND[ARGS]Themostcommonlyusedperfcommandsare:annotateReadperf.data(createdbyperfrecord)anddisplayannotatedcodearchive......
  • linux 文件名乱码 文件名出现问号 批量修改文件名
    linux文件名乱码文件名出现问号原因:创建文件的批处理文件使用windows编辑的,因为windows的换行是\r\n,而linux换行是\n,出现一些乱码如何处理: 1.linux批量重名名  2.dos2unix把Windows文件转换格式 LinuxShell批量重命名的方法1、删除所有的.bak后缀:rename's/\.bak$......
  • linux 中top命令显示完整的command
    命令比较长时,显示不全(全称,全名),可以用top-c  ......
  • Linux Centos安装JDK1.8教程
    第一步:先下载JDK1.8,可以去官网下载,也可以直接这里的:下载地址:链接:https://pan.baidu.com/s/1f1EDWvG-GzpQRJaC_W4SpA密码:9pj1先检查是否有安装JDK:#rpm-qa|grepjdk先把系统自带的干掉(如果没有直接跳过):   rpm-e--nodepsjava-1.7.0-openjdk-1.7.0.45-2.4.3.3.el6.x86_64......
  • Linux高频命令
    1.sed字符替换用法;sed's/原字符串/替换字符串/'单引号里面,s表示替换,三根斜线中间是替换的样式,特殊字符需要使用反斜线”\”进行转义。单引号”‘’”是没有办法用反斜线”\”转义的,这时候只要把命令中的单引号改为双引号就行了,格式如下:#要处理的字符包含单引号se......
  • Linux认证 | RHCA是什么等级的证书?考到工资能有多少?
    RHCA就是红帽认证架构师,RHCA是红帽公司在红帽认证工程师(RHCE)和红帽认证技师(RHCT)认证推出之后又一个最新的顶级认证,在业界也是最受欢迎的、最成熟的linux认证。那么RHCA是什么等级的证书?考到工资多少呢?下面我们就来了解一下吧。01RHCA是什么等级的证书?红帽认证分为三个等级:红帽认证......
  • Linux下内存buff/cache占用过多问题解决
    在Linux下经常会遇到buff/cache内存占用过多问题,如果buff/cache占用过大的,free空闲内存就很少,影响使用;通常内存关系是:普通机器:total=used+free虚拟机器:total=used+free+buff/cache这个时候可以看到buff/cache占用的内存非常大,这个时候可以使用一下命令去清除一下cache内存echo1>......
  • Linux基础命令(一)
    ls就是list的缩写,通过ls命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录、文件夹、文件权限)查看目录信息等常用参数://列出目录所有文件,包含以.开始的隐藏文件ls-a//列出除.及..的其它文件ls-A//反序排列ls-r//以文件修改时间排序ls......
  • Linux 日志管理
    rsyslog介绍日志(Log)是记录和存储计算机、软件、应用或其他系统的操作和事件的文件或数据流。它们可以为系统管理员、开发人员和最终用户提供详细的背景信息,以帮助他们了解和诊断系统的行为。rsyslog是一个开源的日志处理工具,一般用在类Unix系统上,是syslogd的扩展。它提供了更......