首页 > 系统相关 >多进程编程之守护进程Daemonize

多进程编程之守护进程Daemonize

时间:2023-09-11 09:33:54浏览次数:36  
标签:fork 编程 umask rl Daemonize 进程 include 守护

1、守护进程

  守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。所有的守护进程都没有控制终端,其终端名设置为问号。

2、编程规则

  1)首先调用umask函数将文件模式创建屏蔽字设置为一个已知值,通常是0;

  umask函数为进程设置文件模式创建屏蔽字,并返回以前的值。umask也是shell命令,功能和umask函数一样。

1 #include <sys/stat.h>
2 
3 mode_t umask(mode_t mask);

  在进程创建一个新的文件或目录时,如调用open函数创建一个新文件,新文件的实际存取权限是mode与umask按照  mode&~umask运算以后的结果。umask函数用来修改进程的umask。

  首先看一下umask命令的作用:

    首先查看一下当前的umask为022,用vi创建一个umask_3.c,查看该文件的权限为644,修改umask为0,vi创建umask_4.c,查看该文件的权限为666。

     

  umask函数的使用:

    实现函数,首先修改当前进程umask为0.创建fan_test1文件,然后修改umask为006,创建文件fan_test2,输出结果如下图

复制代码
 1 #include <stdio.h>
 2 #include <sys/stat.h>
 3 
 4 int main()
 5 {
 6         umask(0);
 7         if (creat("fan_test1",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) < 0)
 8                 printf("error creat\n");
 9         umask(S_IROTH|S_IWOTH);
10         if (creat("fan_test2",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) < 0)
11                 printf("error creat\n");
12         return 0;
13 }
复制代码

    

  2)调用fork,然后是父进程exit。创建守护进程最关键的一步是调用setsid函数创建一个新的会话(会话是一个或多个进程组的集合),使守护进程成为新会话的首进程,并成为新进程组的组长,失去当前的控制终端,成为一个没有控制终端的进程。而调用函数setsid()之前,要保证当前进程不是进程组的组长,否则该函数返回-1;要保证当前进程不是进程组的组长,就要调用fork,父进程退出;fork创建的子进程和父进程在同一个进程组中,进程组的组长必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,fork之后调用setsid就没有问题了;

  3)调用setsid()函数创建一个新的会话:

       (1) 该进程变成新会话首进程,会话首进程通常是创建该会话的进程,该进程是新会话中的唯一的进程。        (2) 该进程成为一个新进程组的组长进程,新进程组ID就是调用进程的ID。        (3) 该进程没有控制终端,如果在调用setsid之前该进程有一个控制终端,那么这种联系将被中断。

  4)将当前的工作目录更改为根目录。如果守护进程所在的目录为一个挂载的文件系统,那么该文件系统就不能被卸载;另外如果守护进程所在的目录不是根目录,启动守护进程之后,当前工作目录所在的文件夹将不能删除;调用函数chdir("/");

   5)关闭打开的文件描述符;子进程有可能从父进程继承了一些打开的文件,这些文件可能守护进程将不再使用,但这些文件描述符依然消耗系统资源,也有可能导致相关的文件系统无法被卸载。

  关闭文件描述符的方法:

复制代码
 1 方法1:
 2 #include <sys/resource.h>
 3     
 4 struct rlimit    rl;
 5     
 6 if(getrlimit(RLIMIT_NOFILE, &rl) < 0)
 7 {
 8   perror("getrlimit(RLIMIT_NOFILE, &rl)");
 9   return -1;
10 }
11 if(rl.rlim_max == RLIM_INFINITY)
12 {
13   rl.rlim_max = 1024;
14 }
15 for(i = 0; i < rlim_max; i++)
16 {
17   close(i);
18 }
19 方法2:
20 max_fd = sysconf(_SC_OPEN_MAX);
21 for(i = 0; i < max_fd; i++)
22 {
23     close(i);
24 }
复制代码

  6)守护进程打开/dev/null使其具有文件描述符0、1和2,也就是将0、1、2的文件描述符都指向/dev/null; 

1 /*attach file descriptions 0,1 and  2 to /dev/null*/
2 fd0 = open("/dev/null", O_RDWR);
3 fd1 = dup(0);
4 fd2 = dup(0);

  为什么会有这一步操作,守护进程已经脱离终端了,为什么还要将文件描述符0、1、2重定向到/dev/null呢,并且前面已经有了关闭所有文件描述符的操作,文件描述符已经关闭了,在此处为什么还要再打开,两者不是冲突了么?

  7)再次调用fork,使父进程退出;第一次fork()后的子进程已经成为会话组的组长,有权利再调出一个终端,如果出现此情况,则未达到完全脱离终端的目的,此时再调用fork并退出父进程,使得此时的子进程成为完全的后台进程,独立于任何的终端,在第二次fork之前通常会忽略SIGHUP信号,这是因为会话首进程退出时会给该会话中的前台进程组(当打开控制终端后,就有一个前台进程组)的所有进程发送SIGHUP信号,而信号的默认处理函数通常是进程终止,因此需要对信号进程屏蔽处理

 

实现一个守护进程:

复制代码
 1 #include <stdio.h>
 2 #include <sys/stat.h>
 3 #include <signal.h>
 4 #include <sys/resource.h>
 5 #include <unistd.h>
 6 #include <stdlib.h>
 7 void daemonize(void)
 8 {
 9     struct rlimit rl;
10     pid_t pid;
11     struct sigaction sa;
12     int i;
13     umask(0);
14     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
15         printf("error getrlimit\n");
16         exit(0);
17     }
18     if ((pid = fork()) < 0) {
19         printf("error fork\n");
20         exit(0);
21     } else if (pid != 0) {
22         exit(0);
23     }
24     setsid();
25     sa.sa_handler = SIG_IGN;
26     sigemptyset(&sa.sa_mask);
27     sa.sa_flags = 0;
28     if (sigaction(SIGHUP, &sa, NULL) < 0) {
29         printf("error sigaction\n");
30         exit(0);
31     }
32     if (chdir("/") < 0) {
33         printf("error chdir\n");
34         exit(0);
35     }
36     if (rl.rlim_max == RLIM_INFINITY)
37         rl.rlim_max = 1024;
38     for (i = 0; i < rl.rlim_max; i++)
39         close(i);
40 
41     if ((pid = fork()) < 0) {
42          printf("error fork\n");
43          exit(0);
44      } else if (pid != 0) {
45           exit(0);
46      }
47     
48 }
49 
50 int main()
51 {
52     daemonize();
53     while(1) {
54         printf("111111111111111\n");
55         sleep(2);
56     }
57     
58 }
复制代码

标签:fork,编程,umask,rl,Daemonize,进程,include,守护
From: https://www.cnblogs.com/ToTigerMountain/p/17692705.html

相关文章

  • Win32编程之资源文件(三)
    一、菜单资源的使用1.菜单的分类窗口的顶层菜单弹出式菜单系统菜单HMENU类型表示菜单,ID表示菜单项2、菜单资源的使用 (1).注册窗口类时设置菜单 (2).创建窗口传参设置菜单 (3).在主窗口WM_CREATE消息中利用SetMenu函数设置菜单 加载菜单资源HMENULoadMenu( ......
  • unix/linux系统编程第一、二章知识归纳
    1.引言1.1Unix&Linux简介及历史版本Unix和Linux是一系列强大的操作系统,具有丰富的历史和版本。Unix的初始版本由肯·汤普森(KenThompson)和丹尼斯·里奇(DennisRitchie)于20世纪70年代早期开发。它是一种通用操作系统,经典书目包括1988年的《TheCProgrammingLang......
  • Java是一种面向对象的编程语言
    Java是一种面向对象的编程语言,泰兰德幻化广泛应用于各种平台上。它的特点是可移植性强,安全性高,且具有很强的扩展性。Java语言采用了“一次编写,到处运行”的原则,这意味着可以在不同的操作系统和设备上运行相同的Java程序,无需对代码进行修改。Java语言有着丰富的类库和API,可以满足......
  • Golang(又称Go语言)是一种开源的静态强类型编程语
    Golang(又称Go语言)是一种开源的静态强类型编程语言,巧瞒七星解磐键由Google在2007年开始开发,并于2009年发布。它的设计目标是提供一种简洁、高效的语言,同时具备高并发、高性能的特性。Golang的语法风格简洁明了,易于上手,适用于各种规模的项目。下面将介绍Golang在实际应用中的具体案......
  • PHP是一种广泛应用于Web开发的编程语言
    PHP是一种广泛应用于Web开发的编程语言,它具有众多强大的特性和灵活的语法。在本文中,我们将深入探讨PHP的一些具体案例和例子,以帮助您更好地理解并应用它在实际项目中的强大功能。首先,让我们来看一个简单的实例,介绍PHP的核心概念之一:变量。在思密达梦三国PHP中,您可以使用$符号来......
  • socket 编程
    采用socket实现服务端和客户端通信server.c#include<arpa/inet.h>#include<netinet/in.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/socket.h>#include<unistd.h>#defineBUF_SIZE1024#defineM......
  • 【腾讯云 Cloud Studio 实战训练营】 - 云IDE编程之旅化繁为简
    csdn首发文章链接一、前言:随着云计算产业的发展,各种基于云端的IDE相继出现。相比于传统的IDE,云端IDE可以更大程度的提升用户工作的效率。腾讯云与国内领先的一站式软件研发平台CODING联合推出一款完全基于云端的IDE:CloudStudio。作为一款在线云端开发工具,它可以帮助用户减......
  • JavaNote05-面向对象编程01
    0.面向对象内容的三条主线Java类及类的成员:(重点)属性、方法、构造器;(熟悉)代码块、内部类面向对象的特征:封装、继承、多态、(抽象)其他关键字的使用:this、super、package、import、static、final、interface、abstract等1.面向对象编程概述面向对象是软件开发中的一类编程风......
  • 网络编程 1
    网络编程11.1软件架构c/s架构∶全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、美团app、360安全卫士等软件。B/s架构︰全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有IE、谷歌、火狐等。1.要想实现网络通信,需要解决的三个问题:问题1:如何......
  • Unix/Linux 系统编程学习记录
    Unix/Linux系统编程学习记录不定期更新学习笔记、心得与操作过程chapter1引言第一章学习笔记博客链接安装Linux操作系统,学习Linux基础chapter2编程背景第二章学习笔记博客链接课程来源:2021-2022-1信息安全系统设计与实现(上)的平行课程推荐好友20211120destiny......