首页 > 系统相关 >linux基础之守护进程

linux基础之守护进程

时间:2023-07-21 17:11:08浏览次数:31  
标签:fork return setsid linux 进程 id 守护

一.守护进程(Daemon)
1.关于守护进程
守护进程,顾名思义,也就是专门守护一个进程的进程。守护进程的职责就是专门确保被指定的进程的运行。
守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端,并且周期性的执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程,linux的大多数服务器就是用守护进程实现的。比如:Internet服务器inetd。Wed服务器httpd等。同时,守护进程完成了许多系统任务。比如,作业规划进程crond等。

linux系统启动时会启动很多系统服务进程,这些服务进程没有控制终端,不能和用户交互。其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但是系统服务进程不受用户登录注销的影响,他们一直在运行着。这种进程的名称叫做守护进程。

最直接的应用就是重启进程。如果我们的软件崩溃了,为了让软件重新运行起来,软件本身是无法不方便或者无法做到的。因为出故障就是软件本身,而这个故障严重到迫使软件本身挂掉了,自然也没有办法重启自己了。
那么可以借助一个专门的进程来帮助自己启动咯。守护进程当然不仅限于重启进程咯。要实现什么守护功能,就看你怎么实现了。你可以守护进程不被关闭,重启进程,也可以守护进程的网络,必要的配置文件等等。
守护进程好比是保镖,被守护的进程就是保镖保护的对象。守护进程在很多地方都会有应用

二.创建守护进程
1. 关于setsid函数
创建守护进程最关键一步是调用setsid函数创建一个新的Session,并成为Session Leader。

#include<unistd.h>
pid_t setsid(void);
1
2
该函数调用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1。注意:调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不是进程组的Leader很容易,只要先fork再调用setsid就行了。fork的子进程和父进程在同一个进程组中,进程组的Leader必然是该进程组的第一个进程,所以子进程不可能是该组的第一个进程,所以在子进程中调用setsid是一定不会有问题的。

成功创建该函数的结果是:

创建一个新的Seccion,当前进程成为Session Leader,当前进程的id就是Session的id。
创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。
如果当前进程原本有一个控制终端,则他失去这个控制终端,成为一个没有控制终端的进程。所谓失去控制终端是指,原来的控制终端仍然是打开的,仍然可以读写,但是只是一个普通的打开文件,而不是控制终端。
查看守护进程

ps axj |grep -E 'd$'
1

TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程.
由上图可以看出1.我们上篇博客中提到的crond也为守护进程。2. 守护进程都是孤儿进程,因为其父进程的id为0;守护进程自成会话,自称进程组。

2.创建一个守护进程的流程
调用umask将文件模式创建屏蔽字设置为0;
调用fork,父进程退出(exit).原因:1.如果该守护进程是作为一个简单的shell命令启动的,那么父进程终止使得shell认为该命令已经执行完毕。2.保证子进程不是一个进程组的组长进程。
调用setsid创建一个新的会话。 setsid会导致:1 调用进程成为新会话的首进程。2 调用的进程成为进程组的组长进程。3 调用进程没有控制终端。(在此fork一次,保证daemon进程,之后不会打开tty设备)
将当前工作目录更改为根目录。
关闭不再需要的文件描述符。
其他:忽略SIGCHLD信号。
3.创建代码
#include<stdio.h>
#include<unistd.h>
#include<signal.h>

void creat_daemon()
{
umask(0);
pid_t id = fork();
if(id > 0)//father
{
return ;
}
else if(id < 0)
{
perror("fork");
return ;
}

setsid();

close(0);
close(1);
close(2);

signal(SIGCHLD,SIG_IGN);

chdir("/");
}
int main()
{
creat_daemon();
while(1)
{
sleep(1);
}
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
运行结果


4.其他
在网上我们可以看到另外一种版本是用两次fork来创建守护代码如下:

#include<stdio.h>
#include<unistd.h>
#include<signal.h>

void creat_daemon()
{

umask(0);
pid_t id = fork();
if(id > 0)//father
{
return ;
}
else if(id < 0)
{
perror("fork");
return ;
}

setsid();

signal(SIGCHLD,SIG_IGN);

if(id = fork()<0)
{
printf("fork errot\n");
return ;
}
else if(id!=0)
{
return;
}

if(chdir("/")<0)
{
printf("chdir error\n");
return ;
}
close(0);
close(1);
close(2);
}
int main()
{
creat_daemon();
while(1)
{
sleep(1);
}
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
结果如下:

原因如下:

其实现就是心跳互相检测对方是否存在,不存在就启动对方。心跳可使用socket或共享内存什么的。
如果进程比较多,可单独启动一个守护进程进行检测所有进程。守护进程比较简单,出错的可能性比较小。
再或者守护部分写到dll中,所有程序共同调用,但同时只有一个程序执行守护代码。使用内存文件映射保存信息。这样没有单独的守护进程,只要有一个进程在运行,就能保证守护代码在执行。 再或者可以考虑使用看门狗的方式。进程给一块空间定时更新数据,守护代码定时检 测数据更新时间,如果某一进程数据到一定时间超时未更新认为此进程挂掉,重启这个进程。
————————————————
版权声明:本文为CSDN博主「someday1314」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/someday1314/article/details/72942501

 

标签:fork,return,setsid,linux,进程,id,守护
From: https://www.cnblogs.com/im18620660608/p/17571966.html

相关文章

  • 一步一图带你构建 Linux 页表体系 —— 详解虚拟内存如何与物理内存进行映射
    笔者之前在自己的专栏《聊聊Linux内核》里通过大量的篇幅写了一个系列关于内存管理相关的文章,在这个系列文章中,笔者分别通过虚拟内存管理和物理内存管理两个角度算是把Linux内存管理子系统的全貌给大家呈现了出来。但之前的文章都是以专题的形式给大家呈现,采用一种静态的方......
  • Linux 编译安装sshpass
    1、下载地址 wgethttp://sourceforge.net/projects/sshpass/files/sshpass/1.05/sshpass-1.05.tar.gz 2、解压 tarxvzfsshpass-1.05.tar.gz  cdsshpass-1.05.tar.gz  3、编译./configure  make  makeinstall  ......
  • linux账户和权限管理
    一、linux用户账号和组账号概述1.1账户分类linux中,用户一共分为:超级用户普通用户程序用户Linux中每个用户是通过UserId(UID)来唯一标识的新建用户1-60000自动分配0-65535端口号管理员:root,0程序用户:1-499(CentOS6以前),1-999(CentOS7以后)不登录的用户......
  • linux上安装pytorch
    在Linux上安装PyTorchPyTorch是一个基于Python的开源机器学习库,它提供了强大的工具来构建和训练深度学习模型。本文将介绍如何在Linux上安装PyTorch,并提供一些示例代码来帮助您开始使用。步骤1:安装Anaconda要安装PyTorch,我们首先需要安装Anaconda,它是一个用于科学计算的Python发......
  • linux启动redis命令
    Linux启动Redis命令教程作为一名经验丰富的开发者,教授新手如何实现"Linux启动Redis命令"是一项重要任务。在本教程中,我将提供详细的步骤和代码示例,帮助新手顺利启动Redis。整体流程在开始之前,让我们先概括一下整个流程。下表列出了启动Redis的步骤以及每个步骤需要做的事情。......
  • 笨办法学 Linux 中文版 翻译完成
    原书:LearnLinuxTheHardWay(βversion)译者:飞龙自豪地采用谷歌翻译在线阅读PDF格式EPUB格式MOBI格式代码仓库赞助我协议CCBY-NC-SA4.0......
  • linux免安装的redis
    实现“Linux免安装的Redis”1.简介在本篇文章中,我们将介绍如何在Linux系统中实现免安装的Redis。Redis是一个高性能的键值存储系统,常用于缓存、消息队列和实时分析等场景。通过免安装的方式,我们可以快速搭建本地的Redis环境,方便进行开发和测试。2.实施步骤以下表格展示了实施......
  • linux查看docker的ip
    Linux查看Docker的IP作为一名经验丰富的开发者,我很乐意教会刚入行的小白如何在Linux上查看Docker的IP。在本篇文章中,我将向你展示整个流程,并提供每一步需要做的事情和相应的代码。步骤概览以下是查看Docker的IP的整个流程的步骤概览:步骤描述1列出正在运行的Docker容......
  • linux查看Hadoop状态
    Linux查看Hadoop状态简介Hadoop是一个分布式计算框架,用于处理大规模数据集的计算。在开发和调试Hadoop应用程序时,了解集群的状态是非常重要的。本篇文章将介绍如何在Linux环境下查看Hadoop集群的状态。流程下面是查看Hadoop状态的步骤:步骤描述1.登录到Hadoop集群的N......
  • linux安装配置java环境
    Linux安装配置Java环境简介在Linux操作系统上安装和配置Java环境是开发者必备的基础工作之一。本文将向刚入行的小白介绍在Linux系统上安装和配置Java环境的详细步骤和所需的代码。安装配置流程下面是安装配置Java环境的流程概览:步骤描述1下载JavaJDK2安装Java......