【Linux】守护进程
创始人
2024-03-16 14:16:23
0

文章目录

  • 任务管理
    • 进程组
    • 作业
    • 会话
    • 任务管理操作
      • 相关操作
  • 守护进程
    • 创建守护进程
    • daemon函数创建守护进程
    • 所谓的项目部署

任务管理

进程组

进程组是一个或多个进程的集合。每个进程除了有一个进程ID之外,还属于一个进程组。

每个进程组有一个唯一的进程组ID。每个进程组都有一个组长进程。组长进程ID等于其进程组ID。

作业

SHELL终端通过前后台来控制作业和进程组。

一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以运行一个前台作业和任意多个后台作业,这称为作业控制。

会话

会话是一个或者多个进程组的集合

  • 一个会话可以有一个控制终端。建立与控制终端连接的会话首进程被称为控制进程。

  • 一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组。

  • 一个会话包括:一个控制进程,一个前台进程和多个后台进程。

创建四个死循环程序

image-20221203235748418

下面将job1和job2放在一个进程组,job3和job4放在一个进程组

image-20221204000416339

  • TTY:与进程关联的终端(tty)(完整的终端名称)
  • SID:会话组ID

这些进程组的控制终端相同,它们同属于一个会话。

任务管理操作

直接运行某一可执行程序,例如./可执行程序,此时默认将程序放到前台运行,在前台运行的进程的状态后有一个+号,例如s+

image-20221204001421344

运行可执行程序时在后面加上&,可以指定将程序放到后台运行,例如./可执行程序 &

image-20221204001551468

[1] 7358
[2] 7460

每创建一个后台进程组(作业),就会提升一条[ num ] NUM的信息;这里[ num ]是作业的编号。NUM是该作业中某个进程的进程ID。

相关操作

job命令

job命令,可以查看当前会话有那些工作

image-20221204004045827

fg命令

使用fg命令(foreground),可以将某个作业提至前台运行,如果该作业正在后台运行则直接提至前台运行,如果该作业处于停止状态,则给进程组的每个进程发SIGCONT信号使它继续运行并提至前台。

image-20221204004322628

job1和job2的状态从S变为了S+。

需要注意的是:前台进程只能有一个,当一个进程变成前台进程后,bash会自动变为后台进程,此时bash就无法进行命令行解释了。

image-20221204004652440

bash相关进程的+都没有了。

bg命令

使用bg命令,可以让某个停止的作业在后台继续运行(Running),本质就是给该作业的进程组的每个进程发SIGCONT信号。

image-20221204005329747

守护进程

守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程,它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。

Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。

其他进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着,这种进程有一个名称叫守护进程。

Linux系统中存在大量的守护进程,下面使用ps ajx命令查看。

image-20221204005744803

  • TPGID为终端的前台进程组。TPGID为-1的就是守护进程

创建守护进程

守护进程的创建步骤如下:

  1. 设置文件掩码为0。
  2. 忽略SIGCHLD信号。
  3. fork,终止父进程,保持子进程不是会话首进程,从而保证后续不会再和其他终端相关联。
  4. 将子进程设置为一个独立的会话
  5. 将标准输入、标准输出、标准错误重定向到/dev/null。

为什么需要将子进程设置为一个单独的会话,而不是父进程?

一般在一个多进程工作中,父进程即为进程组的组长。而组长管理整个进程组。

一个守护进程的父进程是init进程,需要单独设为一个会话,不与终端交互;一旦一个进程组的组长被设置为一个守护进程,那么原进程组就没有进程组组长。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
void daemonize()
{umask(0);int fd = 0;// 1. 忽略SIGPIPEsignal(SIGPIPE, SIG_IGN);signal(SIGCHLD,SIG_IGN);	// 2. 更改进程的工作目录// chdir();// 3. 让自己不要成为进程组组长if (fork() > 0){exit(1);}// 4. 设置自己是一个独立的会话setsid();// 5. 重定向0,1,2if ((fd = open("/dev/null", O_RDWR)) != -1) // fd == 3{dup2(fd, STDIN_FILENO);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);// 6. 关闭掉不需要的fdif(fd > STDERR_FILENO) close(fd);}
}

关于/dev/null

/dev/null可以理解为Linux下的垃圾回收箱。我们可以通过把命令的输出重定向到 /dev/null 来丢弃脚本的全部输出。

守护进程不能直接和用户交互,所以可以把守护进程的输出都重定到/dev/null文件中。

daemon函数创建守护进程

int daemon(int nochdir, int noclose);

参数说明:

  • 如果参数nochdir为0,则将守护进程的工作目录该为根目录,否则不做处理。
  • 如果参数noclose为0,则将守护进程的标准输入、标准输出以及标准错误重定向到/dev/null,否则不做处理。

所谓的项目部署

项目部署中很重要的一步就是将服务后台化,这里的后台化就是将进程**变成守护进程,**我们以一个TCP服务端为例

源码地址:

socket · 影中人/test - 码云 - 开源中国 (gitee.com)

int main(int argc, char *argv[])
{if (argc != 2 && argc != 3){Usage(argv[0]);exit(3);}uint16_t port = atoi(argv[1]);std::string ip;if (argc == 3){ip = argv[2];}//将进程守护进程化daemonize();//创建TCP服务器并运行Tcpserver svr(port, ip);svr.init();svr.start();return 0;
}

image-20221204013602018

使用daemon守护进程化

int main(int argc, char *argv[])
{if (argc != 2 && argc != 3){Usage(argv[0]);exit(3);}uint16_t port = atoi(argv[1]);std::string ip;if (argc == 3){ip = argv[2];}//守护进程化daemon(0,0);//创建服务器和运行Tcpserver svr(port, ip);svr.init();svr.start();return 0;
}

image-20221204014153066

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...