potplayer 多个进程_进程组、会话、控制终端概念,如何创建守护进程?

守护进程

782729ddcd202432341ec2de2b1ed9c1.png

概念:

守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程。周期性的执行某种任务或等待处理某些发生的事件。

Linux系统有很多守护进程,大多数服务都是用守护进程实现的。比如:像我们的tftp,samba,nfs等相关服务。

UNIX的守护进程一般都命名为*d的形式,如httpd,telnetd等等。

生命周期:

守护进程会长时间运行,常常在系统启动时就开始运行,直到系统关闭时才终止。

守护进程不依赖于终端

从终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。咱们平常写进程时,一个死循环程序,咱们不知道有ctrl+c的时候,怎么关闭它呀,是不是关闭终端呀。也就是说关闭终端的同时也关闭了我们的程序,但是对于守护进程来说,其生命周期守护需要突破这种限制,它从开始运行,直到整个系统关闭才会退出,所以守护进程不能依赖于终端。

查看守护进程

ps axj a: 显示所有 x:显示没有控制终端的进程 j:显示与作业有关的信息(显示的列):会话期ID(SID),进程组ID(PGID),控制终端(TT),终端进程组ID(TRGID)

816c18db85fe25c7cce32e6f8a966aa8.png

• 所有的守护进程都是以超级用户启动的(UID为0); • 没有控制终端(TTY为?); • 终端进程组ID为-1(TPGID表示终端进程组ID,该值表示与控制终端相关的前台进程组,如果未和任何终端相关,其值为-1; • 所有的守护进程的父进程:

历史上,Linux 的启动一直采用init进程;下面的命令用来启动服务。这种方法有两个缺点:1. 启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。2. 启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,这往往使得脚本变得很长。

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。

进程组、会话、控制终端

• 进程组

shell里的每个进程都属于一个进程组,创建进程组的目的是用于简化向组内所有进程发送信号的操作,即如果一个信号是发给一个进程组,则这个组内的所有进程都会受到该信号【方便管理】。

• PGID进程组ID

进程组内的所有进程都有相同的PGID,等于该组组长的PID。(进程组组长:进程组中有一个进程担当组长。进程组ID(PGID)等于进程组组长的进程ID。已知一个进程,要得到该进程所属的进程组ID可以调用getpgrp。一个进程可以通过另一个系统调用setpgrp来加入一个已经存在的进程组或者创建一个新的进程组。

如果内核支持_POSIX_JOB_CONTROL(该宏被定义)则内核会为Shell 上的每一条命令行(可能由多个命令通过管道等连接)创建一个进程组。从这点上看,进程组不是进程的概念,而是shell上才有,所以在task_struct里并没有存储进程组id之类的变量。

进程组的生命周期到组中最后一个进程终止或其加入其他进程组(离开本进程组)为止。

会话

一般一个用户登录后新建一个会话,每个会话也有一个ID来标识(SID)。登录后的第一个进程叫做会话领头进程(session leader),通常是一个shell/bash。对于会话领头进程,其PID=SID。

控制终端

一个会话一般会拥有一个控制终端用于执行IO操作。会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端。与控制终端建立连接的会话领头进程也称为控制进程 (controlling process) 。一个会话只能有一个控制终端。

前台进程组

该进程组中的进程能够向终端设备进行读、写操作的进程组。例如登陆shell(例如bash)通过调用int tcsetpgrp(int fd, pid_t pgrp); 函数设置为某个进程组pgrp关联终端设备fd,该函数执行成功后,该进程组pgrp成为前台进程组。

后台进程组

该进程组中的进程只能够向终端设备写。

终端进程组ID

每个进程还有一个属性,终端进程组ID(TPGID),用来标识一个进程是否处于一个和终端相关的进程组中。前台进程组中的进程的TPGID=PGID,后台进程组的PGID≠TPGID。若该进程和任何终端无关,其值为-1。通过比较他们来判断一个进程是属于前台进程组,还是后台进程组。

进程组、对话期和控制终端关系

9b5eb6a2469ddf3d12bfeef90f551b04.png

进程组、对话期和控制终端关系

  1. 每个会话有且只有一个前台进程组,但会有0个或者多个后台进程组。
  2. 产生在控制终端上的输入(Input)和信号(Signal)将发送给会话的前台进程组中的所有进程。对于输出(Output)来说,则是在前台和后台共享的,即前台和后台的打印输出都会显示在屏幕上。
  3. 终端上的连接断开时 (比如网络断开或 Modem 断开), 挂起信号将发送到控制进程(controlling process) 。
  4. 一个用户登录后创建一个会话。一个会话中只存在一个前台进程组,但可以存在多个后台进程组。第一次登陆后第一个创建的进程是shell,也就是会话的领头进程,该领头进程缺省处于一个前台进程组中并打开一个控制终端可以进行数据的读写。当在shell里运行一行命令后(不带&)创建一个新的进程组,命令行中如果有多个命令会创建多个进程,这些进程都处于该新建进程组中,shell将该新建的进程组设置为前台进程组并将自己暂时设置为后台进程组。

举例

  1. 打开第一个终端执行命令:
ping 127.0.0.1 -aq | grep icmp &  // 通过管道将两个命令串接起来ping –q不显示timeout信息,将其设置到后台并running
  1. 在第一个终端继续执行命令,在前台再新建一个进程组。【注意没有&】
ping 127.0.0.1 -aq | grep icmp //在前台再新建一个进程组,
  1. 开启第二个终端并运行
 ps axj | grep pts/0      即过滤只看pts/0里的会话 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND 2109  2111  2111  2111 pts/0     2538 Ss    1000   0:01 bash 2111  2503  2503  2111 pts/0     2538 S     1000   0:00 ping 127.0.0.1 -aq 2111  2504  2503  2111 pts/0     2538 S     1000   0:00 grep --color=auto icmp 2111  2538  2538  2111 pts/0     2538 S+    1000   0:00 ping 127.0.0.2 -aq 2111  2539  2538  2111 pts/0     2538 S+    1000   0:00 grep --color=auto timeo

• SID都是2111,说明大家都在一个Session里 • 有三个进程组PGID 2111,2503和2538。 我们可以看到用|连起来的ping和grep是在一个进程组里的。 • 2538这个进程组是一个前台的进程组,因为其PGID==TGPID, 2503这个进程组是一个后台进程组

  1. 在第一个终端中执行Ctrl+C
  2. 在第二个终端里继续ps axj | grep pts/0
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND 2109  2111  2111  2111 pts/0     2111 Ss+   1000   0:01 bash 2111  2503  2503  2111 pts/0     2111 S     1000   0:00 ping 127.0.0.1 -aq 2111  2504  2503  2111 pts/0     2111 S     1000   0:00 grep --color=auto icmp

• 2538那个前台进程组的所有进程都消失了,说明信号会发给前台进程组的所有进程 • 2111,即bash所在的那个进程组成为了前台进程组。

守护进程创建流程

守护进程创建流程如下:

1. 创建子进程,父进程退出 2. 在子进程中创建新会话 3. 改变当前目录为根目录 4. 重设文件权限掩码 5. 关闭文件描述符 

1.创建子进程,父进程退出

由于守护进程是脱离控制终端的,因此,完成第一步后就会在shell终端里造成一程序已经运行完毕的假象。之后的所有后续工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而在形式上做到了与控制终端的脱离。

由于父进程已经先于子进程退出,会造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程,就会自动由1号进程收养。原先的子进程就会变成init进程的子进程。

2. 在子进程中创建新会话

setsid()函数的作用。一个进程调用setsid()函数后,会发生如下事件:

• 首先内核会创建一个新的会话,并让该进程成为该会话的leader进程,• 同时伴随该session的建立,一个新的进程组也会被创建,同时该进程成为该进程组的组长。• 该进程此时还没有和任何控制终端关联。若需要则要另外调用tcsetpgrp,前面讲前台进程组时介绍过。

调用setsid()有以下3个作用:

• 让进程摆脱原会话的控制。• 让进程摆脱原进程组的控制。• 让进程摆脱原控制终端的控制。

那么,在创建守护进程时为什么要调用setsid()函数呢?

读者可以回忆一下创建守护进程的第一步,在那里调用了fork()函数来创建子进程再令父进程退出。由于在调用fork()函数时,子进程全盘复制了父进程的会话期、进程组和控制终端等,虽然父进程退出了,但原先的会话期、进程组和控制终端等并没有改变,因此,还不是真正意义上的独立。而setsid()函数能够使进程完全独立出来,从而脱离所有其他进程和终端的控制。

详细见man 2 setsid。

3.改变当前目录为根目

这一步也是必要的步骤。使用fork()创建的子进程继承了父进程的当前工作目录。

由于在进程运行过程中,当前目录所在的文件系统(如“/mnt/usb”等)是不能卸载的,这对以后的使用会造成诸多的麻烦(如系统由于某种原因要进入单用户模式)。

因此,通常的做法是让“/”作为守护进程的当前工作目录,这样就可以避免上述问题。当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数是chdir()。

4. 重设文件权限掩码

文件权限掩码是指屏蔽掉文件权限中的对应位。

例如,有一个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork()函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。

因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。设置文件权限掩码的函数是umask()。在这里,通常的使用方法为umask(0)。即赋予最大的能力。

5. 关闭文件描述符

同文件权限掩码一样,用fork()函数新建的子进程会从父进程那里继承一些已经打开的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法被卸载。

在上面的第(2)步之后,守护进程已经与所属的控制终端失去了联系,因此,从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf())输出的字符也不可能在终端上显示出来。

所以,文件描述符为0、1和2的3个文件(常说的输入、输出和报错这3个文件)已经失去了存在的价值,也应被关闭。

代码实现

/* 关注一口Linux*/#include  #include  #include  #include #include #include  #include #include int main(){ pid_t pid; int i, fd; char *buf = "This is a Daemon"; pid = fork(); if (pid  0) {  exit(0);  } /* 第二步 */ setsid(); /* 第三步 */   chdir("/");   /* 第四步 */ umask(0); /* 第五步 */   for(i = 0; i 

执行结果

a7b3e6946472e81e4abb00370d84ec6c.png

由上图可见: • 守护进程./run 的UID为0; • 没有控制终端(TTY为?); • 终端进程组ID为-1; • 守护进程的父进程为1516,即systemd。

71429ba29f37143596cef738cfcd269e.png

更多Linux干货,请关注: 一口Linux

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

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

相关文章

acs880 用户手册_华中数控、广州数控系统用户手册

数控加工仿真系统 广州数控系统用户手册上海宇龙软件工程有限公司2004 年 5 月华中数控、广州数控系统用户手册 目录I目录第一章 基本操作 ............................................................................................ 1 1.1 项目文件 ...................…

亚马逊出的平板电脑_美国最畅销的安卓平板电脑,还只有2GB内存

在美国除了iPad,谁家的平板电脑卖得最好?不是华为小米,也不是微软或谷歌,而是Amazon亚马逊。主打入门级定位的亚马逊Fire系列平板电脑,在北美的平板市场上,有着举足轻重的地位。今天,亚马逊正式…

对接kafka_Kafka系列9:面试题是否有必要深入了解其背后的原理?我觉得应该刨根究底(上)...

​前言在本文开始之前,作者一直有个疑惑,就是面试题是只写写问题和答案就草草了事,还是应该深入分析一下其背后发生的一些原理。和朋友探讨以后作者还是决定采用后者的方式,因为我认为不仅要做到知其一,更要知其二&…

资源不足的情况怎么设置sparkrdd并行度_监控录像机资源不足或达到上限的原因及解决方法!...

在安装网络监控摄像机过程中,很多人遇到硬盘录像机画面上提升“资源不足”或性能“达到上限”的问题,新手遇到这样的问题会选择重启录像机,但是几次反复发现并不能解决。监控录像机资源不足或达到上限的原因及解决方法!首先这种提…

主动变被动9个例句_高中英语 :主动表被动的适用范围

1. 表衡量的动词。The room measures 5 by 6.2. sell, write, wash, read, wear, keep, drink等表状态的情况下。The pen writes well. The clothes wash well.3. 在动词不定式中主语发出的动作。I have a lot of work to do.4. 动词不定式前面的词为形容词时。The question …

为什么要重写hashcode方法和equals方法

为什么要重写hashcode方法和equals方法 我们可能经常听到说重写equals方法必须重写hashcode方法,这是为什么呢?java中所有的类都是Object的子类,直接上object源码 /** Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights …

python代码_python爬虫19 | 遇到需要的登录的网站怎么办?用这3招轻松搞定!

你好由于你是游客无法查看本文请你登录再进谢谢合作当你在爬某些网站的时候需要你登录才可以获取数据咋整?莫慌小帅b把这几招传授给你让你以后从容应对那么接下来就是学习 python 的正确姿势登录的常见方法无非是这两种1、让你输入帐号和密码登录2、让你输入帐号密码…

利用电脑上自带指纹识别嵌入程序中_Win 10 隐藏功能:不用任何软件就可实现手机投屏到电脑...

投屏工具我也介绍了不少,所有的都是需要安装第三方软件的。不过,其实 Windows 10 就自带了手机投影到电脑的功能,不需要任何软件就能实现。在设置中打开系统,找到投影到此电脑,在红框中根据你的需要设置好,…

为什么要重写hashCode()方法和equals()方法以及如何进行重写

一、前言 本篇文章主要探讨的问题有三个: 1、首先我们为什么需要重写hashCode()方法和equals()方法? 2、在什么情况下需要重写hashCode()方法和equals()方法? 3、如何重写这两个方法? 二、为什么需要重写hashCode()方法和equal…

bloomberg用法 固定收益_内部收益率的用法浅谈某保险的真实收益率

公司财务课程,魏教授讲得非常棒,治愈了大家的瞌睡,激起了大家的学习热情。我一直认为,大牛在讲课,吹牛还是演讲中,都能够给现场观众提供强大的能量,使得彼此运行在同一个共振频率。内部收益率(I…

联想小新锐7000主板型号_2020年高性价比游戏本选购推荐指南——7000价位游戏本推荐...

玩电脑的老猫,只说你最想听的话!大家好,我是老猫,这段时间很多小伙伴问我,多少钱能买到一台不错的游戏本呢?知乎中很多人说5000元买游戏本,就是等于买一台“电子垃圾”虽然5000元的游戏本不是非…

Java重写equals方法时为什么要重写hashCode方法

在我们平时编写Java代码时,重写equals方法时一定要重写hashCode方法,这是为什么呢? 在讨论这个问题前,我们先看下Object类中hashCode方法和equals方法。 hashCode方法: 翻译如下: equals方法:…

iot nb 曹淑敏 鹰潭_移动物联时代来啦 鹰潭一项成就为全球首个 江西力争在全国“四个领先”...

移动物联网是基于移动通信网络的物联网技术体系,主要由NB-IoT(窄带物联网技术)、eMTC(增强机器类通信技术)、蜂窝网的未来演进技术5G(第五代移动通信技术)三种技术共同构成。江西网络广播电视台9月1日讯(记者 李希文)9月1日下午,江西省工信委、中国信息通…

RPC(一)[概述]

文章目录RPC-概述简介1.服务的调用过程2.RPC框架1.Dubbo–电商2.Motan–互联网3.Thrift4.gRPC5.RPCX3.RPC 和 RESTful1.RPC over HTTP 和 RESTful2.RPC over TCP 和 RESTfulRPC-概述 简介 远程过程调用(Remote Procedure Call,缩写为 RPC)是…

epic登陆按钮一直在转_双剑合璧!GOG GALAXY 2.0官方支持Epic商店集成

2020年7月21日晚,GOG官方宣布提供与Epic商城的集成服务,这也是GOG GALAXY 2.0推出以来又一次与超大型游戏平台达成的合作。现在玩家可以通过GOG GALAXY 2.0管理、安装和启动来自Epic商城的游戏。需要注意的是,因为这次行为是完全官方的&#…

用 Java 实现人脸识别功能

引言 人脸识别SDK 人脸识别技术是很复杂的,自己用Java手撕一个识别算法有点不切实际,毕竟实力不允许我这么嚣张,还是借助三方的SDK吧! 找了一圈发现一个免费的人脸识别SDK: ArcSoft:,地址:ht…

有没有词匹配算法_Google Ads 再次扩展了关键字变量匹配

在过去的几年里,Google Ads已经扩大了使用相近的关键字变量。Google改变的匹配类型不仅包括拼写错误和复数,还包括功能词、修改和重新排序。日前,谷歌再次扩展了相近变量的使用。短语匹配和广泛匹配修饰语以下是2019年7月31日谷歌官方广告公告…

mysql 组合查询_MySQL组合查询教程

#MYSQL#这是我MySQL的第八篇教程。本篇主要介绍的是MySQL的组合查询的用法。在大多数的SQL查询中都只包含从一个或者多个表中返回数据的单条SELECT语句,MySQL其实也支持允许执行多条SELECT语句,并将结果作为单个结果集返回,这些组合查询通常称…

Java后端 + 百度SDK实现人脸识别

Java后端 百度SDK实现人脸识别 人工智能越来越贴近我们的生活,相信大家也经常接触到人脸识别,手机付款、app注册验证、门禁等等。 如果要用Java后台使用这些功能,那么需要怎么做呢?请看完下面这篇文章,就能轻松、简单…

路由器局域网设置_路由器基础介绍

路由器已经商用很多年了,但是一些SSID, DHCP, 这些名词都还没有搞懂,遇到路由器问题,不知所措,只能求助于网管。但是有些问题是很简单的,只要稍微去学习就可以解决问题。下面介绍路由器的一些简单问题。路由…