会话、前台进程组、后台进程组、孤儿进程等相关概念

Linux进程组和会话

终端登录:

当系统自举时,内核创建ID为1的进程,也就是init进程,init进程系统进入多用户状态。

init进程读取/etc/inittab,对每一个允许登录的终端设备,init调用一次fork,它所生成的子进程执行(exec)getty程序。

getty为终端设备调用open函数,如果没有请求则阻塞,如果有请求,则文件描述符0,1,2就设置到该设备,然后getty输出”login“等的信息并等带用户输入用户名。

当用户键入用户名后,getty的工作就完成了。

然后以类似于这样的方式调用login程序

execle(“/bin/login”,“login”,“-p”,username,(char*)0,envp);

init以空环境(即无envp参数)调用一个getty,gettty以终端名和gettytab中说明的环境字符串。-p标识通知login保留传递给它的环境,也可将其他环境字符串加到该环境中,但

是不要替换它。

 
 

一、进程

  传统上,Unix操作系统下运行的应用程序、 服务器以及其他程序都被称为进程,而Linux也继承了来自unix进程的概念。必须要理解下,程序是指的存储在存储设备上(如磁盘)包含了可执行机器指 令(二进制代码)和数据的静态实体;而进程可以认为是已经被OS从磁盘加载到内存上的、动态的、可运行的指令与数据的集合,是在运行的动态实体。这里指的 指令和数据的集合可以理解为Linux上ELF文件格式中的.text .data数据段。


二、进程组

  每个进程除了有一个进程ID之外,还属于一个进程组,那什么是进程组呢?
  顾名思义,进程组就是一个或多个进程的集合。这些进程并不是孤立的,他们彼此之间或者存在父子、兄弟关系,或者在功能上有相近的联系。每个进程都有父进程,而所有的进程以init进程为根,形成一个树状结构。

  那为啥Linux里要有进程组呢?其实,提供进程组就是为了方便对进程进行管理。假设要完成一个任务,需要同时并发100个进程。当用户处于某种原因要终止 这个任务时,要是没有进程组,就需要手动的一个个去杀死这100个进程,并且必须要严格按照进程间父子兄弟关系顺序,否则会扰乱进程树。有了进程组,就可以将这100个进程设置为一个进程组,它们共有1个组号(pgrp),并且有选取一个进程作为组长(通常是“辈分”最高的那个,通常该进程的ID也就作为进程组的ID)。现在就可以通过杀死整个进程组,来关闭这100个进程,并且是严格有序的。组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在某个进程组中一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。

   进程必定属于一个进程组,也只能属于一个进程组。 一个进程组中可以包含多个进程。 进程组的生命周期从被创建开始,到其内所有进程终止或离开该组。

  内核中,sys_getpgrp()系统调用用来获取当前进程所在进程组号;sys_setpgid(int pid, int pgid)调用用来设置置顶进程pid的进程组号为pgid。


三、作业
       一个正在执行的进程称为一个作业,而且作业可以包含一个或多个进程,尤其是当使用了管道和重定向命令。例如“nroff -man ps.1|grep kill|more”这个作业就同时启动了三个进程。
作业控制指的是控制正在运行的进程的行为。比如,用户可以挂起一个进程,等一会儿再继续执行该进程。shell将记录所有启动的进程情况,在每个进程过程中,用户可以任意地挂起进程或重新启动进程。作业控制是许多shell(包括bash和tcsh)的一个特性,使用户能在多个独立作业间进行切换。
       一 般而言,进程与作业控制相关联时,才被称为作业。

       在大多数情况下,用户在同一时间只运行一个作业,即它们最后向shell键入的命令。但是使用作业控制,用户可以同时运行多个作业,并在需要时在这些作业间进行切换。这会有什么用途呢?例如,当用户编辑一个文本文件,并需要中止编辑做其他事情时,利用作业控制,用户可以让编辑器暂时挂起,返回shell提示符开始做其他的事情。其他事情做完以后,用户可以重新启动挂起的编辑器,返回到刚才中止的地方,就象用户从来没有离开编辑器一样。这只是一个例子,作业控制还有许多其他实际的用途。


作业控制(jobcontrol)

        是shell的另一个特性,它允许用户同时运行多个作业而产生,并且根据需求可将前后台的作业进行切换。当启动某个作业时,它通常是运行在前台,因此该作业是与终端相连接的。利用作业控制这一功能,可将正处于前台工作的作业切换到后台去,在后台该作业可继续运行,并且在前台可以监视另一个作业。如果想关注一下某个正在后台运行的作业,那么可将其切换到前台工作,以使其又一次与终端相连接。作业控制的这一概念起源于BSDUNIX,后来又出现在CShell中。


四、会话

  再看下会话。由于Linux是多用户多任务的分时系统,所以必须要支持多个用户同时使用一个操作系统。当一个用户登录一次系统就形成一次会话 。一个会话可包含多个进程组,但只能有一个前台进程组。每个会话都有一个会话首领(leader),即创建会话的进程。 sys_setsid()调用能创建一个会话。必须注意的是,只有当前进程不是进程组的组长时,才能创建一个新的会话。调用setsid 之后,该进程成为新会话的leader。

  一个会话可以有一个控制终端。这通常是登陆到其上的终端设备(在终端登陆情况下)或伪终端设备(在网络登陆情况下)。建立与控制终端连接的会话首进程被称为控制进程。一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组。所以一个会话中,应该包括控制进程(会话首进程),一个前台进程组和任意后台进程组。 

  一次登录形成一个会话

  一个会话可包含多个进程组,但只能有一个前台进程组


五、控制终端

  会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端 (SVR4/Linux)  
  与控制终端建立连接的会话领头进程称为控制进程 (session leader) 
  一个会话只能有一个控制终端 
  产生在控制终端上的输入和信号将发送给会话的前台进程组中的所有进程 
  终端上的连接断开时 (比如网络断开或 Modem 断开), 挂起信号将发送到控制进程(session leader)

  进程属于一个进程组,进程组属于一个会话,会话可能有也可能没有控制终端。一般而言,当用户在某个终端上登录时,一个新的会话就开始了。进程组由组中的领头进程标识,领头进程的进程标识符就是进程组的组标识符。类似地,每个会话也对应有一个领头进程。
  同一会话中的进程通过该会话的领头进程和一个终端相连,该终端作为这个会话的控制终端。一个会话只能有一个控制终端,而一个控制终端只能控制一个会话。用户通过控制终端,可以向该控制终端所控制的会话中的进程发送键盘信号。

      shell可以同时运行一个前台作业和任意多个后台作业,一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,这称为作业控制。可以通过fg和bg命令控制作业的前后台运行。由于一个session只能有一个前台进程组,如果某个进程组需要在前台运行,shell所在的进程组就自动变为后台进程组。

孤儿进程组

POSIX定义为:该组中的每个成员要么是该组的一个成员,要么不是该组所属会话的成员(一个进程组中的所有进程的父进程要么是该进程组的一个进程,要么不是该进程组所在的会话中的进程。一个进程组不是孤儿进程组的条件是,该组中有一个进程其父进程在属于同一个会话的另一个组中。)

简单来说:有bash产生的新进程组中,至少有一个进程的PPID指向该bash,否则该进程组成为孤儿进程组,无法将进程状态改变通知bash

POSIX要求系统向孤儿进程中处于停止状态的每一个进程发送挂断信号(SIGHUP),接着又向其发送继续信号(SIGCONT)对挂断信号的默认动作是终止该进程(注意终止

进程和停止进程是有区别的,停止指暂停,终止指退出)


为什么有孤儿进程组

       当一个终端控制进程(即会话首进程)终止后,那么这个终端可以用来建立一个新的会话。这可能会产生一个问题,原来旧的会话(一个或者多个进程组的集合)中的任一进程可再次访问这个的终端。为了防止这类问题的产生,于是就有了孤儿进程组的概念。当一个进程组成为孤儿进程组时,posix.1要求向孤儿进程组中处于停止状态的进程发送SIGHUP(挂起)信号,系统对于这种信号的默认处理是终止进程,然而如果无视这个信号或者另行处理的话那么这个挂起进程仍可以继续执行。    

       有孤儿进程,对应的也有孤儿进程组的概念。为何引入这个概念以及这个概念的引入需要OS的实现者作些什么呢?先看两个前提,首先,posix用一个session的概念来描述一次用户的登录以及该用户在此次登录后的操作,然后用作业的概念描述不同操作的内容,最后才用进程的概念描述不同操作中某一个具体的工作;其次,unix最初将所有的进程组织成了树的形式,这样就便于追踪每个进程也便于管理,有了上述两个前提事情就很明白了,一切都是为了便于管理,一切都是为了登录用户的安全,即此次登录用户的作业是不能被下个登录用户所控制的,即使它们的用户名一致也是不行的,因此所谓的孤儿进程组简单点说就是脱离了创造它的session控制的,离开其session眼线的进程组,unix中怎样控制进程,怎样证明是否在自己的眼线内,那就是树形结构了,只要处于以自己为根的子树的进程就是自己眼线内的进程,这个进程就是受到保护的,有权操作的,而在别的树枝上的进程原则上是触动不得的,unix中建立进程使用fork,自然地这么一“叉子”就形成了自己的一个树枝,当然在自己眼线了,一般对于登录用户而言一个会话起始于一次login之后的shell,只要该用户不logout,在该终端的shell上执行的所有的非守护进程都是该shell的后代进程,因此它们组成一个会话,全部在shell的眼线中,一个会话终止于会话首长的death。现在考虑一下终端上的shell退出后的情景,按照规定,该终端上所有的进程都过继给了别的进程,大多数情况是init进程,然后紧接着另外一个用户登录了这个终端或者知道前一个登录用户密钥的另一个有不好念头的人登录了该终端,当然为其启动的shell创建了一个新的session,由于之前登录的用户已退出,现在登录的用户由于之前用户的进程组都成了孤儿进程组,所以它再有恶意也不能控制它们了,那些孤儿进程组中的成员要么继续安全的运行,要么被shell退出时发出的SIGHUP信号杀死。
 
需要注意的
      一般一个登录shell就是一个会话首进程,会话首进程获得一个控制终端给前台进程组用,会话首进程也只能通过控制终端来控制别的进程,所谓的控制就是发送信号(如ctl+c等)
 
一些函数
获得进程组id
#include<unistd.h>
pid_t getpgrp(void); 返回值:调用进程的进程组id
 
#include<unistd.h>
int setpgid(pid_t pid,pid_t pgid); 返回值:成功返回0,出错返回-1


Setpgid函数将pid进程的进程组id设置为pgid,
(1)如果两个参数相等,则由pid指定的进程变成进程组组长。
(2)如果pid为0,则使用调用者的进程id
(3)如果pgid为0,则由pid指定的进程id用作进程组id
 
#include<unistd.h>
pid_t setsid(void); 返回值:成功返回进程组id,若出错返回-1

如果调用此函数的进程不是一个进程组的组长,则此函数就会创建一个新会话,结果会发生下面三件事:
(1)该进程变为会话首进程。此时,该进程是新会话中的唯一进程
(2)该进程成为一个新进程组的组长进程。新进程的组id是调用进程的进程id。
(3)该进程没有控制终端。如果在调用setsid之前该进程有一个控制终端,那么也会被中断
如果调用进程调用进程是一个进程组的组长,则此函数返回出错。为了保证不会出错,通常先调用fork,然后使其父进程终止,而子进程则继续。因为子进程继承了父进程的进程组id,而其进程id则是重新分配的,两个不肯能相等,所以这就保证子进程不会是一个进程组的组长。
 
#include<unistd.h>
pid_t tcgetpgrp(int filedes);返回值:成功则返回前台进程组id,出错返回-1
int tcsetpgrp(int fileds ,pid_t pgrpid);返回值:成功返回0,出错返回-1


tcgetpgrp返回前台进程组的进程组id,该前台进程组与在fileds上打开的终端相关联
tcsetpgrp将前台进程组id设置为pgrpid,pgrpid应是在同一会话中的一个进程组的id。fileds必须引用该会话的控制终端。
 
#include<termios.h>
pid_t tcgetsid(int filedes); 返回值:成功返回会话首进程的进程组id,出错返回-1.
需要管理控制终端的应用程序可以调用tcgetsid函数识别出控制终端的会话首进程的会话id
 
观察进程组id与进程id需要用到的命令
ps  -o pid,ppid,pgrp,session,tpgid,comm
其中pgrp表示进程组id,tpgid表示前台进程组id,comm表示启动该进程的命令。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在现有省、市港口信息化系统进行有效整合基础上,借鉴新 一代的感知-传输-应用技术体系,实现对码头、船舶、货物、重 大危险源、危险货物装卸过程、航管航运等管理要素的全面感知、 有效传输和按需定制服务,为行政管理人员和相关单位及人员提 供高效的管理辅助,并为公众提供便捷、实时的水运信息服务。 建立信息整合、交换和共享机制,建立健全信息化管理支撑 体系,以及相关标准规范和安全保障体系;按照“绿色循环低碳” 交通的要求,搭建高效、弹性、高可扩展性的基于虚拟技术的信 息基础设施,支撑信息平台低成本运行,实现电子政务建设和服务模式的转变。 实现以感知港口、感知船舶、感知货物为手段,以港航智能 分析、科学决策、高效服务为目的和核心理念,构建“智慧港口”的发展体系。 结合“智慧港口”相关业务工作特点及信息化现状的实际情况,本项目具体建设目标为: 一张图(即GIS 地理信息服务平台) 在建设岸线、港口、港区、码头、泊位等港口主要基础资源图层上,建设GIS 地理信息服务平台,在此基础上依次接入和叠加规划建设、经营、安全、航管等相关业务应用专题数据,并叠 加动态数据,如 AIS/GPS/移动平台数据,逐步建成航运管理处 "一张图"。系统支持扩展框架,方便未来更多应用资源的逐步整合。 现场执法监管系统 基于港口(航管)执法基地建设规划,依托统一的执法区域 管理和数字化监控平台,通过加强对辖区内的监控,结合移动平 台,形成完整的多维路径和信息追踪,真正做到问题能发现、事态能控制、突发问题能解决。 运行监测和辅助决策系统 对区域港口与航运业务日常所需填报及监测的数据经过科 学归纳及分析,采用统一平台,消除重复的填报数据,进行企业 输入和自动录入,并进行系统智能判断,避免填入错误的数据, 输入的数据经过智能合,自动生成各业务部门所需的数据报 表,包括字段、格式,都可以根据需要进行定制,同时满足扩展 性需要,当有新的业务监测数据表需要产生时,系统将分析新的 需求,将所需字段融合进入日常监测和决策辅助平台的统一平台中,并生成新的所需业务数据监测及决策表。 综合指挥调度系统 建设以港航应急指挥中心为枢纽,以各级管理部门和经营港 口企业为节点,快速调度、信息共享的通信网络,满足应急处置中所需要的信息采集、指挥调度和过程监控等通信保障任务。 设计思路 根据项目的建设目标和“智慧港口”信息化平台的总体框架、 设计思路、建设内容及保障措施,围绕业务协同、信息共享,充 分考虑各航运(港政)管理处内部管理的需求,平台采用“全面 整合、重点补充、突出共享、逐步完善”策略,加强重点区域或 运输通道交通基础设施、运载装备、运行环境的监测监控,完善 运行协调、应急处置通信手段,促进跨区域、跨部门信息共享和业务协同。 以“统筹协调、综合监管”为目标,以提供综合、动态、实 时、准确、实用的安全畅通和应急数据共享为核心,围绕“保畅通、抓安全、促应急"等实际需求来建设智慧港口信息化平台。 系统充分整合和利用航运管理处现有相关信息资源,以地理 信息技术、网络视频技术、互联网技术、移动通信技术、云计算 技术为支撑,结合航运管理处专网与行业数据交换平台,构建航 运管理处与各部门之间智慧、畅通、安全、高效、绿色低碳的智 慧港口信息化平台。 系统充分考虑航运管理处安全法规及安全职责今后的变化 与发展趋势,应用目前主流的、成熟的应用技术,内联外引,优势互补,使系统建设具备良好的开放性、扩展性、可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值