zoukankan      html  css  js  c++  java
  • Linux _守护进程 浅解

    守护进程

    1. 什么是守护进程
      守护进程,也称Daemon进程
      守护进程,是Linux的后台服务进程。

      普通进程和终端的关系:
      用户与系统交流的界面,称为“终端”。
      当在某个终端上运行某个进程时,该终端就称为该进程的“控制终端”。
      当控制终端关闭时,它对应的进程(在该终端上启动的进程)都将被自动关闭。

      守护进程和终端的关系:
      守护进程不依赖于任何终端。
      守护进程启动后,将一直运行到系统关闭.

    2. 什么时候使用守护进程
      如果希望某个进程不要受到用户、终端的影响,则可以把该进程实现为“守护进程”。

    3. 守护进程的编写
      步骤:
      1) 使该进程脱离控制台
      (1) 创建一个子进程,
      接着关闭该子进程的父进程。
      使得该子进程变成孤儿进程,进而被init收养,称为init的子进程。
      即:
      pd = fork();
      if (pd > 0) {
      exit(0);
      }

      (2) 在子进程中创建新会话
           即:
               setsid();
               作用:使该进程脱离原控制终端的控制。
                       使该进程脱离原进程组的控制。
                       使该进程脱离原会话的控制。
      
          补充:
          进程组: 进程组,就是一个、或多个进程的集合。
                      每个进程组,都有一个“进程组ID”
                      每个进程组,都有一个组长进程,其组长进程进程的PID就是进程组的“进程组ID”
      
          会话:一个会话是一个、或多个进程组的集合。
                  一个会话,开始于用户登录,终止于该用户退出。
      

      2)改变该进程的当前目录。
      该进程的当前目录继承自父进程。
      把该进程的当前目录改为根目录。
      方法:chdir();

      3) 改变文件权限掩码
      该进程的文件权限掩码,继承自父进程。
      方法:umask()
      一般使用umask(0), 即放开所有屏蔽。

      补充:
      文件权限掩码:
      不是指文件的访问权限。
      例:如果某文件的文件权限掩码是050,
          则表示,该文件的文件组拥有者,没有读权限、没有写权限。
      

      4)关闭文件描述符
      该进程的文件描述符,继承自其父进程。
      而,守护进程已不可能在终端上输出、输入,所以文件描述符0,1,2都不会再用。
      其他已继承下来的文件描述符也不再使用。
      所以,需要关闭文件描述符,以节省资源。
      即:
      for (i=0; i

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <syslog.h>
    #include <sys/klog.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define FILE_NAME "test.txt"
    #define BUFF_SIZE  80
    
    int main(void)
    {
        pid_t pd;
        int i;
        int fd_max;
        int fd;
        time_t cur_time;
        char buff[BUFF_SIZE];
        int ret;
    
        pd = fork();
        if (pd == -1) {
            printf("fork failed!
    ");  //¥À ±printfªπø…“‘ π”√
            exit(1);        
        } else if (pd > 0) {
            exit(0);
        }
    
        setsid();
        chdir("/");
        umask(0);
        fd_max = getdtablesize();
        for (i=0; i<fd_max; i++) {
            close(i);
        }
    
           //÷¡¥À£¨ ÿª§Ω¯≥Ã¥¥Ω®Õͱœ
    
        // ¥Úø™syslog∑˛ŒÒ
        openlog("my daemon", LOG_PID, LOG_DAEMON);
        fd = open(FILE_NAME, O_WRONLY | O_CREAT, 0666);
        //fd = open(FILE_NAME, O_WRONLY);
        if (fd == -1) {
            syslog(LOG_ERR, "open file %s failed!
    ", FILE_NAME);
            exit(1);
        }
    
        syslog(LOG_INFO, "open file %s succeed!
    ", FILE_NAME);
    
        while(1) {
            time(&cur_time);
            sprintf(buff, "%s", ctime(&cur_time));
            ret = write(fd, buff, strlen(buff) + 1);
            if (ret == -1) {
                syslog(LOG_ERR, "write file %s failed!
    ", FILE_NAME);
                exit(1);
            }
            sleep(5);
        }
    
        closelog();
           return 0;    
    }
    
    
  • 相关阅读:
    【leetcode】106. Construct Binary Tree from Inorder and Postorder Traversal
    【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal
    【leetcode】236. Lowest Common Ancestor of a Binary Tree
    【leetcode】235. Lowest Common Ancestor of a Binary Search Tree
    【leetcode】352. Data Stream as Disjoint Intervals
    【leetcode】897. Increasing Order Search Tree
    【leetcode】900. RLE Iterator
    BEC listen and translation exercise 26
    BEC listen and translation exercise 25
    BEC listen and translation exercise 24
  • 原文地址:https://www.cnblogs.com/Sico2Sico/p/5384203.html
Copyright © 2011-2022 走看看