Linux守护进程

进程组和会话在 UNIX 系统中是非常重要的概念,特别是在进行作业控制和终端会话管理时。下面是关于进程组和会话的详细解释:

进程组(Process Group)

  1. 定义与作用

    • 进程组是一个或多个进程的集合,这些进程通常是从同一个作业启动的,共享同一个进程组标识符(PGID)。例如,一个复杂的命令行管道操作(如 cmd1 | cmd2)中的所有进程可以属于同一个进程组。
    • 进程组使得操作系统可以方便地对一组相关进程执行操作,如发送信号。
  2. 进程组首进程

    • 每个进程组有一个首进程,这是创建该组的进程,其进程 ID(PID)同时作为该进程组的 ID。
    • 进程组首进程在创建时设置组 ID,并可以通过特定的系统调用(如 setpgid())修改自己或其他进程的进程组归属。
  3. 生命周期

    • 进程组的生命周期从首进程创建该组开始,直到最后一个进程退出该组时结束。
    • 进程可能会因为终止自身或被其他信号杀死而离开进程组,或者它可以调用系统函数切换到另一个进程组。

会话

会话(session)管理是 UNIX 系统中处理进程组和终端交互的重要机制。这里提供对您提到的各个点的更深入的解释:

会话首进程与会话 ID
  • 会话首进程:创建新会话的进程自动成为该会话的首进程。这通常发生在用户登录时或者当一个进程通过调用 setsid() 系统调用来显式创建一个新会话。
  • 会话 ID:新会话的创建同时生成一个新的会话标识符(session ID),该标识符等于该会话首进程的进程 ID (PID)。新创建的进程会继承其父进程的会话 ID,除非它们显式地创建或加入一个新的会话。
控制终端
  • 建立控制终端:控制终端通常在会话首进程首次打开一个终端设备时被建立。控制终端是会话中进程交互的主要方式,如读取用户的键盘输入和输出信息到屏幕。
  • 终端与会话的关系:一个终端设备在任一时间点最多只能是一个会话的控制终端。一旦终端被某个会话首次占用,其他会话将无法将其设置为控制终端。
前台与后台进程组
  • 前台进程组:在任何给定时刻,会话中只有一个进程组可以成为前台进程组。这个组的进程可以直接从控制终端接收输入,这对于交互式应用非常关键。
  • 后台进程组:不在前台的进程组称为后台进程组。这些进程组不能直接从控制终端读取输入,这样设计可以避免输入冲突和管理复杂度。
信号处理与终端字符
  • 终端字符生成信号:用户在控制终端输入特定的键(如 Ctrl+C)会生成信号(如 SIGINT),这些信号会被发送到前台进程组的所有进程。这允许用户可以直接与运行在前台的进程组交互,例如中断正在执行的命令。
控制进程
  • 会话首进程的角色:一旦控制终端的连接建立,会话首进程也成为控制进程。这意味着它负责处理来自控制终端的信号和可能的终端断开(如用户注销)。

通过这些机制,UNIX 系统提供了强大的工具来管理和控制多个进程和它们的交互,这对于构建稳定和可管理的多用户环境是必要的。

进程组、会话、控制终端之间的关系

在 UNIX 系统中,进程组、会话和控制终端之间的关系是协调进程之间通信和控制的关键机制。这些概念相互作用,支持复杂的作业控制和会话管理,特别是在多用户环境中。下面是这些概念之间关系的详细解释:

1. 进程组(Process Group)

进程组是一种逻辑分组,用于将一系列相关的进程组织在一起,以便于统一管理。通常情况下,这些进程是从同一个命令行启动的,比如一个 shell 脚本中的多个命令。进程组内的每个进程都共享同一个进程组标识符(PGID),使得操作系统可以方便地对整个组发送信号。

2. 会话(Session)

会话是一或多个进程组的更高级别的集合。每个会话可以包含多个进程组,包括前台和后台进程组。会话通常在用户登录时开始,用户的登录 shell 成为会话首进程,并且会创建一个新的会话。这个会话首进程有权申请或分配一个控制终端。

3. 控制终端(Controlling Terminal)

控制终端是会话首进程与用户交互的界面。它通常是一个物理或虚拟的终端设备(如终端窗口)。会话首进程在首次打开一个终端设备时,该设备成为该会话的控制终端。控制终端可以被用来向会话中的进程发送信号(例如,当用户按下 Ctrl+C 时发送 SIGINT)。

关系概述:
  • 会话与进程组:会话是进程组的容器,可以包含多个进程组。在一个会话中,可以指定一个进程组作为前台进程组,其他的则作为后台进程组。前台进程组可以接收来自控制终端的输入,而后台进程组则不能。
  • 会话与控制终端:会话首进程可以为会话获取一个控制终端,这个终端成为整个会话及其所有进程组的交互中心。控制终端可以被用来管理会话中的进程,如发送中断信号。
  • 进程组与控制终端:在有控制终端的会话中,只有前台进程组可以直接从控制终端接收输入和处理特定的控制信号(如 SIGINT)。后台进程组则被限制,不能直接读取控制终端的输入,以防止输入输出冲突。

这种层次和关系的设置使得 UNIX 系统能够有效地管理多任务操作,特别是在多用户和网络环境中,提供了高度的灵活性和控制能力。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

进程组、会话操作函数

在 UNIX 和类 UNIX 系统中,操作进程组和会话的一些核心函数允许程序员在运行时管理进程的组和会话属性。这些函数非常重要,因为它们提供了控制进程如何与操作系统和其他进程交互的能力。

1. 获取和设置进程组
pid_t getpgrp(void);
  • 描述:此函数返回当前进程的进程组 ID。
  • 返回值:返回调用进程的进程组 ID。
pid_t getpgid(pid_t pid);
  • 描述:获取指定进程的进程组 ID。如果 pid 为 0,则返回调用进程的进程组 ID。
  • 参数
    • pid:进程标识符。
  • 返回值:成功时返回进程组 ID,失败时返回 -1 并设置 errno。
int setpgid(pid_t pid, pid_t pgid);
  • 描述:设置指定进程的进程组 ID。这个函数可以用来将进程 pid 加入到进程组 pgid,或者创建一个新的进程组(如果 pid 等于 pgid)。
  • 参数
    • pid:要更改进程组的进程的 ID,如果 pid 是 0,则表示调用进程。
    • pgid:新的进程组 ID,如果 pgid 是 0,则 pid 指定的进程将成为新进程组的首进程。
  • 返回值:成功时返回 0,失败时返回 -1 并设置 errno。

2. 获取和设置会话

pid_t getsid(pid_t pid);
  • 描述:获取指定进程的会话 ID。如果 pid 为 0,则返回调用进程的会话 ID。
  • 参数
    • pid:进程标识符。
  • 返回值:成功时返回会话 ID,失败时返回 -1 并设置 errno。
pid_t setsid(void);
  • 描述:创建一个新的会话,并设置当前进程为该会话的首进程和进程组首进程。当前进程不能是进程组的领头进程。
  • 返回值:成功时返回新会话的会话 ID,失败时返回 -1 并设置 errno。

注意事项

  • 在使用 setpgid()setsid() 时,要注意进程间的权限和状态,因为这些调用可能受到限制,特别是在已经拥有子进程或已属于某个进程组的情况下。
  • 调用 setsid() 时,如果调用者已是某个进程组的领头进程,则该调用会失败。这是为了防止一个已有控制终端的进程逃避终端产生的信号。

这些函数提供了在 UNIX 类操作系统中管理和控制进程组和会话的基本机制,对于实现作业控制、守护进程以及终端会话管理等功能至关重要。

守护进程

守护进程(Daemon process)是 Linux 系统中一个非常核心的概念,对于系统的稳定运行和服务的持续提供至关重要。这些进程通常是在系统启动时启动,并在整个系统运行期间持续运行,直到系统关闭。下面详细解释守护进程的特征和其实现方法:

特征
  1. 长生命周期

    • 守护进程通常在系统启动时创建,例如通过系统的初始化系统(如 systemdinit)自动启动。
    • 它们不会像交互式用户进程那样在任务完成后退出,而是一直运行,直到系统关闭。
  2. 在后台运行

    • 守护进程通常在后台运行,不与任何用户直接交互。
    • 它们通常不拥有控制终端,这防止了终端信号(如 SIGINT 或 SIGQUIT)意外中断它们的运行。
  3. 服务性质

    • 守护进程通常执行周期性任务或等待特定事件的发生,例如监听网络请求或文件系统变化。
    • 例如,HTTP 服务器(如 Apache 的 httpd)、邮件服务器(如 postfix)和文件服务器(如 smbd)都是典型的守护进程。
实现守护进程

这个过程是在 UNIX 和 Linux 系统中常用的模式,用于创建独立于控制终端的后台服务。以下是如何执行这个转换的详细步骤,包括其中涉及的各个系统调用和目的:

1.创建子进程并结束父进程

这个步骤确保了新的守护进程不是一个会话领导者,从而可以调用 setsid() 创建新会话。

pid_t pid = fork();
if (pid < 0) {// 处理错误exit(EXIT_FAILURE);
}
if (pid > 0) {// 父进程直接退出exit(EXIT_SUCCESS);
}
2. 创建新会话

子进程调用 setsid() 创建一个新的会话,成为会话的领导者,脱离任何控制终端。

if (setsid() < 0) {// 处理错误exit(EXIT_FAILURE);
}
3. 清除文件创建掩码(umask)(非必须)

设置 umask 为 0 确保守护进程创建的任何文件和目录都有适当的访问权限。

umask(0);
4. 更改当前工作目录

将当前工作目录改为根目录 /,这可以防止守护进程阻止卸载文件系统。

if (chdir("/") < 0) {// 处理错误exit(EXIT_FAILURE);
}
5. 关闭所有继承的文件描述符

这可以防止守护进程无意中保持打开的文件描述符,可能导致资源泄露或不必要的行为。

int x;
for (x = sysconf(_SC_OPEN_MAX); x >= 0; x--) {close(x);
}
6. 重定向标准文件描述符到 /dev/null

关闭了标准输入、输出和错误(文件描述符 0, 1, 2)后,常见做法是打开 /dev/null 并用 dup2() 使得这些描述符指向 /dev/null。这样,任何尝试读写这些文件描述符的操作都不会有任何效果。

int fd = open("/dev/null", O_RDWR);
dup2(fd, 0); // STDIN
dup2(fd, 1); // STDOUT
dup2(fd, 2); // STDERR
7. 执行核心业务逻辑

在完成所有的设置后,守护进程可以开始执行其核心功能,如周期性检查、处理请求等。

while (1) {// 执行任务sleep(1); // 休眠是为了模拟周期性任务
}

以上步骤创建了一个完全独立的守护进程,它在系统后台安静地运行,几乎不受用户会话影响,适用于需要长时间运行并且不需要用户交互的服务。这种类型的进程是服务器和服务架构的基础。

案例
/*写一个守护进程,每隔2s获取一下系统时间,将这个时间写入到磁盘文件中。
*/#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <signal.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>void work(int num) {// 捕捉到信号之后,获取系统时间,写入磁盘文件time_t tm = time(NULL);struct tm * loc = localtime(&tm);// char buf[1024];// sprintf(buf, "%d-%d-%d %d:%d:%d\n",loc->tm_year,loc->tm_mon// ,loc->tm_mday, loc->tm_hour, loc->tm_min, loc->tm_sec);// printf("%s\n", buf);char * str = asctime(loc);int fd = open("time.txt", O_RDWR | O_CREAT | O_APPEND, 0664);write(fd ,str, strlen(str));close(fd);
}int main() {// 1.创建子进程,退出父进程pid_t pid = fork();if(pid > 0) {exit(0);}// 2.将子进程重新创建一个会话,新的会话会脱离原来的控制终端setsid();// 3.设置掩码umask(022);// 4.更改工作目录chdir("/home/nowcoder/");// 5. 关闭、重定向文件描述符int fd = open("/dev/null", O_RDWR);dup2(fd, STDIN_FILENO);dup2(fd, STDOUT_FILENO);dup2(fd, STDERR_FILENO);// 6.业务逻辑// 捕捉定时信号struct sigaction act;act.sa_flags = 0;act.sa_handler = work;sigemptyset(&act.sa_mask);sigaction(SIGALRM, &act, NULL);struct itimerval val;val.it_value.tv_sec = 2;val.it_value.tv_usec = 0;val.it_interval.tv_sec = 2;val.it_interval.tv_usec = 0;// 创建定时器setitimer(ITIMER_REAL, &val, NULL);// 不让进程结束while(1) {sleep(10);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/328439.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android系统不同版本存储权限

一、Android存储简介 Android系统分为内部存储和外部存储 从Android6.0开始不断在更新存储&#xff08;读写&#xff09;权限&#xff0c;除了在AndroidManifest.xml文件里声明&#xff0c;app运行时也要动态申请使用对应的权限 提醒&#xff1a;应用私有存储不需要动态申请权…

一种基于电场连续性的高压MOSFET紧凑模型,用于精确表征电容特性

来源&#xff1a;A Compact Model of High-Voltage MOSFET Based on Electric Field Continuity for Accurate Characterization of Capacitance&#xff08;TED 24年&#xff09; 摘要 本文提出了一种新的高压MOSFET&#xff08;HV MOS&#xff09;紧凑模型&#xff0c;以消…

【C++】:string类的基本使用

目录 引言一&#xff0c;string类对象的常见构造二&#xff0c;string类对象的容量操作三&#xff0c;string类对象的访问及遍历操作四&#xff0c;string类对象的修改操作五&#xff0c;string类非成员函数六&#xff0c;整形与字符串的转换 引言 string 就是我们常说的"…

JSP技术

前言&#xff1a;虽然现在Vue盛行&#xff0c;但是对于初学者和一些项目我们还是采用jsp技术来编写前端代码&#xff0c;一些老的项目也需要jsp去维护。就像老师说的法国的银行系统还是采用COBOL这种古老语言。本篇文章主要介绍jsp技术。 目录 一、概述 &#xff08;1&#…

思科模拟器--2.静态路由和默认路由配置24.5.15

首先&#xff0c;创建三个路由器和两个个人电脑。 接着&#xff0c;配置两台电脑的IP&#xff0c;子网掩码和默认网关 对Router 0&#xff0c;进行以下命令&#xff1a; 对Router进行以下命令&#xff1a; 对Router2进行以下命令&#xff1a; 本实验完成。 验证&#xff1a;PC…

【嵌入式大赛应用赛道】机械手臂

电机 进步电机&#xff1a;它的转动是以确定的步数进行的&#xff0c;只要计算好脉冲数量和频率&#xff0c;就可以准确预测和控制电机的转动角度、速度以及停止的位置 伺服电机&#xff1a;将输入的电信号&#xff08;如电压或电流指令&#xff09;转换成轴上的精确旋转运动…

Golang RPC实现-day02

导航 Golang RPC实现一、客户端异步并发多个请求1、 客户端结构体2、 一个客户端&#xff0c;异步发送多个请求&#xff0c;使用call结构体代表客户端的每次请求3、客户端并发多个请求4、客户端接收请求 Golang RPC实现 day01 我们实现了简单的服务端和客户端。我们简单总结一…

docker-compose部署gitlab

需要提前安装docker和docker-compose环境 参考&#xff1a;部署docker-ce_安装部署docker-ce-CSDN博客 参考&#xff1a;docker-compose部署_docker compose部署本地tar-CSDN博客 创建gitlab的数据存放目录 mkdir /opt/gitlab && cd mkdir /opt/gitlab mkdir {conf…

石碑之谜:滚动机关

描述 在蒙德和璃月的边界地带&#xff0c;有一个被遗忘的神庙&#xff0c;里面有一个奇怪的机关&#xff1a;滚动石碑。小熊必须操作这个112的长方体石碑&#xff0c;使其通过不同的地面环境&#xff0c;最终放置到神秘的符号“O”上&#xff0c;以解开通往宝藏的大门。 石碑…

如何使用JMeter测试导入接口/导出接口?

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 今天上班&#xff0c;被开发问了一个问题&#xff1a;JM…

OpenHarmony标准设备应用开发(二)——布局、动画与音乐

本章是 OpenHarmony 标准设备应用开发的第二篇文章。我们通过知识体系新开发的几个基于 OpenHarmony3.1 Beta 标准系统的样例&#xff1a;分布式音乐播放、传炸弹、购物车等样例&#xff0c;分别介绍下音乐播放、显示动画、动画转场&#xff08;页面间转场&#xff09;三个进阶…

TypeScript学习日志-第二十四天(webpack构建ts+vue3)

webpack构建tsvue3 一、构建项目目录 如图&#xff1a; shim.d.ts 这个文件用于让ts识别.vue后缀的 后续会说 并且给 tsconfig.json 增加配置项 "include": ["src/**/*"] 二、基础构建 安装依赖 安装如下依赖&#xff1a; npm install webpack -D …

基于网络爬虫技术的网络新闻分析(二)

目录 2 系统需求分析 2.1 系统需求概述 2.2 系统需求分析 2.2.1 系统功能要求 2.2.2 系统IPO图 2.2 系统非功能性需求分析 3 系统概要设计 3.1 设计约束 3.1.1 需求约束 3.1.2 设计策略 3.1.3 技术实现 3.3 模块结构 3.3.1 模块结构图 3.3.2 系统层次图 3.3.3…

VRRP虚拟路由器冗余协议

VRRP概述 VRRP是什么 VRRP&#xff1a;虚拟路由器冗余协议过把几台路由设备联合组成一台虚拟的路由设备&#xff0c;将虚拟路由设备的IP地址作为用户的默认网关实现与外部网络通信当网关设备发生故障时&#xff0c;VRRP能够选举新的网关设备承担数据流量&#xff0c;从而保障…

2024软件测试必问的常见面试题1000问!

01、您所熟悉的测试用例设计方法都有哪些&#xff1f;请分别以具体的例子来说明这些方法在测试用例设计工作中的应用。 答&#xff1a;有黑盒和白盒两种测试种类&#xff0c;黑盒有等价类划分法&#xff0c;边界分析法&#xff0c;因果图法和错误猜测法。白盒有逻辑覆盖法&…

大模型日报2024-05-15

大模型日报 2024-05-15 大模型资讯 OpenAI推出全新AI模型GPT-4o&#xff0c;具备文本、图像和音频处理能力 摘要: OpenAI公司继ChatGPT后&#xff0c;最新推出了名为GPT-4o的AI模型。这一模型不仅能够理解和生成文本&#xff0c;还新增了图像和音频的解释及生成功能。GPT-4o作为…

【Web】CTFSHOW 单身杯 题解

目录 web签到 easyPHP 姻缘测试 web签到 用data协议包含php标签闭合 payload: filedata://text/plain,<?php system($_GET[1]);?>>?;)]1[TEG_$(metsys php?<,nialp/txet//:atadeasyPHP 一眼awk命令执行 payload: cmdawk&param{system("ta…

基于单片机的智能安防系统设计(32+4G+WIFI版)-设计说明书

设计摘要&#xff1a; 本设计基于STM32单片机&#xff0c;旨在实现一个智能安防系统&#xff0c;主要包括烟雾和温度传感器、人体红外传感器、显示屏、按键、4G模块和WiFi模块等组件。通过这些组件的协作&#xff0c;实现了火灾检测、入侵监测、状态显示、用户交互和远程通信等…

静态NAT

哈喽&#xff01;各位小伙伴们好久不见&#xff0c;最近由于工作的原因断更了一段时间&#xff0c;不过最近我都会把这些给补上&#xff0c;今天我们来学习一个简单的知识——静态NAT转换。 第一章 什么是NAT技术&#xff1f; 网络地址转换技术NAT&#xff08;Networ…

【RSGIS数据资源】2001-2021 年亚洲季风区主要国家作物种植制度数据集

文章目录 1. 数据集概况2. 数据格式3. 文件名命名规则4. 数据生产服务单位5. 元数据6. 数据引用与参考文献引用 1. 数据集概况 2001-2021 年亚洲季风区主要国家作物种植制度数据集&#xff08;ACIA500&#xff09;是结合MODIS 影像和现有的土地利用等多源数据&#xff0c;基于…