zoukankan      html  css  js  c++  java
  • linux 守护进程编程

    概述:

    • Daemon运行在后台也称作“后台服务进程”。 它是没有控制终端与之相连的进程。它独立于控制终端、通常周期的执行某种任务。
    • 守护进程脱离终端是为了避免进程在执行过程中的信息在任何终端上显示并且进程也不会被任何终端所产生的任何终端信息所打断。
    • 由于在Linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依赖这个终端,这个终端就称为这些进程的控制终端。
    • 当控制终端被关闭时,相应的进程都会自动关闭。但是守护进程却能突破这种限制,它被执行开始运转,直到整个系统关闭时才退出。
    • 进程组:是一个或多个进程的集合。进程组由进程组ID来唯一标识。除了进程号(PID)之外,进程组ID(GID)也是一个进程的必备属性。每个进程都有一个组长进程,其组长进程的进程号等于进程组ID。且该进程组ID不会因为组长进程的退出而受影响。
    • 会话周期:会话期是一个或多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。
    • 控制终端:由于在linux中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依赖这个控制终端。

    守护进程的特性:

    1. 守护进程最重要的特性是后台运行。
    2. 守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符、控制终端、会话和进程组、工作目录已经文件创建掩码等。这些环境通常是守护进程从父进程那里继承下来的。
    3. 守护进程的启动方式有其特殊:它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。

    daemon进程编程流程:

    1.创建子进程,父进程退出

    2.摆脱当前会话,创建新的会话组,子进程成为组长

    3.关闭文件描述符号

    4.设置文件掩码

    5.设置工作目录

    注意:有时还要处理SIGCHLD信号signal(SIGCHLD, SIG_IGN);防止僵尸进程(zombie))

    下面就可以添加任何你要daemon做的事情

     

    示例:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <string.h>
     4 #include <stdlib.h>
     5 #include <sys/types.h>
     6 #include <sys/stat.h>
     7 #include <sys/wait.h>
     8 
     9 
    10 int main(int argc, const char *argv[])
    11 {
    12     int ret;
    13     int i;
    14     char * buf = "hello world";
    15     pid_t pid;
    16     FILE * fp;
    17         
    18     pid = fork();
    19     if(pid < 0){
    20         perror("fork");
    21         return -1;
    22     }
    23     else if(pid > 0){
    24         exit(0);    //父进程退出
    25     }
    26 
    27 
    28     setsid();    //让子进程成组长  并创建新的会话  并脱离当前终端
    29 
    30 
    31 //关闭标准输入流
    32     for(i=0;i<3;i++){
    33         close(i);
    34     }
    35 
    36 //更改工作目录至根目录  (可选)
    37     chdir("/");
    38 
    39 //设置文件掩码 (可选)
    40     umask(0);
    41 
    42 
    43 //守护进程间隔一段时间向文件写入内容
    44     while(1){
    45     
    46         fp = fopen("daemon.log","a+");
    47         if(!fp){
    48             return -1;
    49         }
    50 
    51         ret = fwrite(buf,1,strlen(buf),fp);
    52         if(ret < 0){
    53             return -1;
    54         }
    55 
    56         fclose(fp);
    57 
    58         sleep(5);
    59     }
    60 
    61     return 0;
    62 }

     

  • 相关阅读:
    SpringBoot Jpa 双数据源mysql + oracle + liquibase+参考源码
    C#:将字符串中连续空格作为分隔符获取多段模糊查询的字符串
    C# 传入参数2021-05-18T00:00:00.000Z使用ToDateTime日期在此基础上加8小时
    修改DbContext并不是线程安全的bug处理。
    产品经理推荐书籍
    抽象类、类和接口
    git 分支合并主干出现冲突的解决办法
    HttpClient请求设置Content-Type标头空格问题
    C# 3Des加密解密
    WPF 颜色选择器
  • 原文地址:https://www.cnblogs.com/general0878/p/7221203.html
Copyright © 2011-2022 走看看