zoukankan      html  css  js  c++  java
  • linux 进程通信之 守护进程

    守护进程(Daemon)

    Daemon(精灵)进程,是linux中的后台服务进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的时间。一般采用以d结尾的名字。从下面的进程信息可以看出,守护进程都是【?】。

    colord    1160  0.0  0.2 399424 14520 ?        Ssl  6月06   0:00 /usr/lib/colord/colord
    

    Linux后台的一些系统服务进程,没有控制终端,不能直接和用户交互。不受用户登录,注销的影响,一直在运作着,他们都是守护进程。如ftp服务器;nfs服务器等。

    创建守护进程,最关键的一步是调用setsid函数创建一个新的会话(session),并成为session leader。

    会话和进程组

    会话比进程组更高一级,多个进程组对应一个会话。

    多个进程在同一个进出组,第一个进程是进程组的组长。

    组长(父进程)不可以创建会话,必须是组员(子进程)创建。

    可以用【ps ajx】查看session id

    创建会话(session)

    1,创建会话的进程不能是组长进程(父进程)

    2,创建会话成功的进程,变成组长进程(父进程)

    3,新会话的进程丢弃原来的终端控制

    4,建立新会话时,先调用fork,终止父进程,子进程调用创建会话的函数setsid

    #include <sys/types.h>
    #include <unistd.h>
    pid_t setsid(void);
    
    
    DESCRIPTION
           setsid()  creates a new session if the calling process is not a process
           group leader.  The calling process is the leader  of  the  new  session
           (i.e., its session ID is made the same as its process ID).  The calling
           process also becomes the process group leader of a new process group in
           the session (i.e., its process group ID is made the same as its process
           ID).
    
           The calling process will be the only process in the new  process  group
           and in the new session.
    

    普通的进程为什么不是守护进程?因为,普通的进程在终端执行,当关闭终端时,终端会给这个终端里执行的所有进程发送信号SIGHUP,这个信号的默认处理的中断进程。所以,当终端被关闭时,所以的进程都被终止了,不能成为守护进程。

    Signal     Value     Action   Comment
    ──────────────────────────────────────────────────────────────────────
    SIGHUP        1       Term    Hangup detected on controlling terminal
                                         or death of controlling process
    
    

    创建守护进程的步骤:

    1,创建子进程,终止父进程

    2,在子进程中调用函数setsid,来创建新会话

    3,改变当前进程的目录。chdir函数

    4,重新设置文件权限的掩码。umask函数

    5,关闭0,1,2文件描述符。守护进程用不到0,1,2文件描述符。避免浪费资源。

    6,开始执行守护进程的核心代码。

    7,推出守护进程,一般执行不到这里,因为一直在循环里。

    例子:每分钟做一个文件

    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/time.h>
    #include <time.h>
    #include <signal.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #define _FILE_ "%s/log/data_%ld"
    
    void catc(int num){
      char* host = getenv("HOME");
      char buf[256] = {0};
      sprintf(buf, _FILE_, host, time(NULL));
      
      int fd = open(buf, O_WRONLY|O_CREAT, 0664);
      if(fd < 0){
        perror("open:");
        exit(1);
      }
      close(fd);
    }
    int main(){
    
      //创建子进程
      pid_t pid = fork();
      //关闭父进程
      if(pid > 0){
        exit(0);
      }
    
      //创建新会话
      setsid();
    
      //设置掩码
      umask(0);
    
      //改变工作目录
      chdir(getenv("HOME"));
    
      //关闭文件描述符
      close(0),close(1),close(2);
    
      //设置定时器
      struct itimerval it = {{60, 0}, {1, 0}};
      setitimer(ITIMER_REAL, &it, NULL);
    
      //捕捉信号SIGALRM
      struct sigaction act;
      act.sa_flags = 0;
      sigemptyset(&act.sa_mask);
      act.sa_handler = catc;
      sigaction(SIGALRM, &act, NULL);
      
      while(1)
        sleep(1);
    }
    

    守护进程扩展了解

    普通的进程也能强行变成守护进程。使用命令【nohup】。

    它的作用是,阻塞信号SIGHUP,也就是当终端被关闭时,信号SIGHUP被阻塞了,所以进程就没有被终止。

    nohup ./a.out >> a.log &
    

    命令解释:

    • ./a.out:要执行的程序
    • 把输出重定向到a.log
    • &:后台执行的意思

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    SMO学习笔记(五)——附加数据库
    SMO学习笔记(二)——还原(恢复)篇之完整恢复
    加深C# 中字符串前加@符号理解以及使用~~
    Oracle Sys用户用默认密码change_on_install 无法登录的问题(错误代码:ORA28009)
    Reflector for .NET 下载问题
    SQLSERVER拆分字符串的函数(表值函数)
    AjaxPro使用Session出错(AjaxPro "Session"引发了"System.NullReferenceException"类型的异常)
    ASP.NET Web页面(.aspx)添加用户控件(.ascx)无显示的问题
    公积金贷款与商业贷款的区别(在废打印纸中的意外收获... :))
    SMO学习笔记(三)——效验数据库备份文件
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/10988899.html
Copyright © 2011-2022 走看看