终端 进程关系

1.终端登录

登录过程:内核--->init[进程ID=1]--->(fork)init--->(exec)getty--->(exec)--->login

登录结束过程:进程1=init->登录shell<->终端设备驱动程序<->使用终端的用户

2.网络登录

如下图

3.进程组

1).每个进程属于一个进程组,这个进程组从同样的终端获得信号

函数getpgrp返回调用进程的进程组ID,结果也用pid_t表示:

#include <unistd.h>

pid_t getpgrp(void);
//返回调用进程的进程组ID。

2)SUS定义getpgid函数作为一个XSI扩展来效仿1)中函数的行为

#include <unistd.h>

pid_t getpgid(pid_t pid);
//成功返回进程组ID,错误返回-1

如果pid为0,返回调用进程的进程组ID。因而getpgid(0)等价于getpgrp();

3).每个进程组可以有一个进程组长。这个组长和它的进程组ID相等的进程ID于来标识(Leader的ProcessID = Process Group ID)。可能一个进程组长会创建一个进程组、创建这个组的进程,然后终止。只要至少有一个进程在这个组里,这个进程组便仍然存在,不管进程组长是否终止。一个进程加入一个存在的进程组或创建一个新的进程组,通过调用setpgid:

#include <unistd.h>

int setpgid(pid_t pid, pid_t pgid);
//成功返回0,错误返回-1

setpgid函数将pid进程的进程组ID设置为pgid。如果两个参数相等,则由pid指定的进程成为进程组长。如果pid为0,那么使用调用者的进程ID。同样,如果pgid为0,由pid指定的进程ID作为进程组ID被使用。

PS:一般使进程设置其子进程的进程组ID,并且使子进程设置其中经的进程组ID

4.会话

会话是一个或多个进程组的集合,下面一个会话中有三个进程组

进程调用setsid函数来建立一个新的会话

#include <unistd.h>

pid_t setsid(void);
//返回进程组ID;错误返回-1

如果调用进程不是一个进程组长,那么这个函数创建一个新的会话。有三件事发生:

1).该进程变成新会话的会话首进程。(会话首进程是创建该会话的进程。)该进程是这个新会话里的唯一进程。

2).该进程变为一个新进程组的进程组长。新进程组ID就是该调用进程的进程ID。

3).该进程没有控制终端。如果进程在调用setsid之前有一个控制终端,那么这个关联被中断。

PS:如果调用者已经是一个进程组长,那么这个函数返回一个错误。为了保证不出现这种情况,通常的做法是调用fork,然后使父进程终止,而让子进程继续。

getsid函数返回一个进程的会话领导的进程组ID

#include <unistd.h>

pid_t getsid(pid_t pid);
//返回会话领导的进程组ID,错误返回-1

如果pid为0,getsid返回调用进程的会话领导的进程组ID。由于出于安全原因考虑,一些实现可能有如下限制:如果pid不属于调用者所在的会话,调用进程不能得到会话领导的进程组ID。

5.控制终端

会话和进程组有几个其它的特性::

1).会话可以有单一的控制终端。这通常是在登录到其上的终端设备(在终端登录的情况下)或者伪终端设备(在网络登录的情况下)。

2).建立与控制终端连接的会话首进程被称为控制进程。

3).一个会话里的几个进程组可以被分为一个前台进程组和一个或多个后台进程组。

4).如果一个会话有一个控制终端,那么它有一个前台进程组,而在这个会话里的所有其它进程组都是后台进程组。

5).每当我们输入终端的中断键(经常是DELETE或Control-C),就会将中断信号发送给前台进程组的所有进程。

6).无论何时我们输入终端的退出键(经是Control+\),就会将退出信号发送给前台进程组的所有进程。

7).如终端接口检测到调制解调器或者网络连接断开连接,则将挂起信号发送给控制进程(会话首进程)。

6.tcgetpgrp、tcsetpgrp和tcgetsid函数

需要一种方法来告诉内核哪个进程组是前台进程组,这样终端设备驱动程序卡就能了解终端输入和终端产生的信号到何处。

#include <unistd.h>

pid_t tcgetpgrp(int filedes);
//返回前台进程组的进程组ID;错误返回-1

int tcsetpgrp(int filedes, pid_t pgrpid);
//返回0,错误返回-1

函数tcgetpgrp返回和在filedes上打开的终端相关联的前台进程组的进程组ID。如果进程有一个控制终端,进程可以调用tcsetpgrp来设置前台进程组ID给pgrpid。

SUS定义了一个XSI扩展,被称为tcgetsid,来允许一个应用程序来得到会话领导的进程组ID,给定一个控制TTY的文件描述符。

#include <termios.h>

pid_t tcgetsid(int filedes);
//返回会话领导的进程组ID。错误返回-1

需要管理控制终端的应用程序可以使用tcgetsid来标识控制终端会话首进程的会话ID(它等价于会话首进程的进程组ID)。

7.作业控制

作业控制要求三种形式的支持:

(1) 支持作业控制的shell。

(2) 内核中的终端驱动程序必须支持作业控制。

(3) 必须提供对某些作业控制信号的支持

8.shell执行程序

这里仅给出实例 详见APUE

shell命令:

ps -o pid,ppid,pgid,sid,comm | cat1 | cat2

其输出:

PID    PPID   PGID   SID   COMMAND
949    947     949    949      sh
1888  949     949    949      cat2
1889  1823   949    949      ps
1890  1988   949    949      cat1

该管道中的最后一个进程是shell的子进程,而执行管道中其他命令的进程则是该最后进程的子进程

9.孤儿进程组

一个父进程已终止的进程称为孤儿进程(orphan process),这种进程由init进程收养。

时间: 2024-07-30 00:42:59

终端 进程关系的相关文章

Linux系统开发7 进程关系,守护进程

[本文谢绝转载原文来自http://990487026.blog.51cto.com] <大纲> Linux系统开发7  进程关系守护进程 终端 网络终端 Linux PCB结构体信息 进程组 修改子进程.父进程的组ID 会话组 设置一个会话脱离控制终端 生成一个新的会话 守护进程 守护进程模板 获取当前系统时间  终端 在UNIX系统中用户通过终端登录系统后得到一个Shell进程这个终端成为Shell进 程的控制终端Controlling Terminal在讲进程时讲过控制终端是保存在PCB

09.进程关系

1.终端登录 BSD终端登录 a.系统管理员创建通常名为/etc/ttys的文件,其中,每个终端设备都有一行,每一行说明设备名和传递给getty程序的参数,例如,参数之一说明了终端的波特率等. 当程序自举时,内核创建进程ID为1的进程,也就是init进程.init进程使系统进入多用户状态.init进程读文件/etc/ttys,对每一个允许登录的终端设备,init调用一次fork,它所生成的子进程则执行(exec)getty程序. fork and exec init --------------

APUE学习笔记:第九章 进程关系

9.1 引言 本章将更详尽地说明进程组以及POSIX.1引入的会话的概念.还将介绍登陆shell(登录时所调用的)和所有从登陆shell启动的进程之间的关系. 9.1 终端登陆 系统管理员创建通常名为/etc/ttys的文件,其中每个终端设备都有一行,每一行说明设备名传递给getty程序的参数.当系统自举时,内核创建进程ID为1的进程,依旧是init进程.init进程使系统进入多用户状态.init进程读文件/etc/ttys,对每一个允许登陆的终端设备,init调用一次fork,所生成的子进程则

Linux进程关系

Linux进程关系 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux的进程相互之间有一定的关系.比如说,在Linux进程基础中,我们看到,每个进程都有父进程,而所有的进程以init进程为根,形成一个树状结构.我们在这里讲解进程组和会话,以便以更加丰富的方式了管理进程. 进程组 (process group) 每个进程都会属于一个进程组(process group),每个进程组中可以包含多个进程.进程组会有一个进程组领

(七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程

. . . . . 目录 (一) 一起学 Unix 环境高级编程(APUE) 之 标准IO (二) 一起学 Unix 环境高级编程(APUE) 之 文件 IO (三) 一起学 Unix 环境高级编程(APUE) 之 文件和目录 (四) 一起学 Unix 环境高级编程(APUE) 之 系统数据文件和信息 (五) 一起学 Unix 环境高级编程(APUE) 之 进程环境 (六) 一起学 Unix 环境高级编程(APUE) 之 进程控制 (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系

Linux 进程(二):进程关系及其守护进程

进程关系 进程组 进程组是一个或多个进程的集合.通常,它们是在同一作业中结合起来的,同一进程组中的各进程接收来自同一终端的各种信号,每个进程组有一个唯一的进程组ID.每个进程组有一个组长进程,该组长进程的ID等于进程组ID.从进程组创建开始到最后一个进程离开为止的时间称为进程组的生命周期. #include <unistd.h> pid_t getpgrp(void); 返回值:调用进程的进程组ID int setpgid(pid_t pid, pid_t pgid); 返回值:成功,返回0:

apue学习笔记(第九章 进程关系)

本章将详细地说明进程组以及POSIX.1引入的会话的概念.还将介绍登录shell和所有从登录shell启动的进程之间的关系 终端登录 BSD终端登录.系统管理者创建通常名为/etc/ttys的文件,其中每个终端设备都有一行,用来说明设备名和传到getty程序的参数. 当系统自举时,内核创建进程ID为1的进程(init进程).init进程读取文件/etc/ttys,对每一个允许登录的终端设备调用一次fork,它所生成的子进程则exec getty程序,如下图所示: getty对终端设备调用open

父子进程关系

1)父进程先于子进程终止: 此种情况就是我们前面所用的孤儿进程.当父进程先退出时,系统会让init进程接管子进程 . 2)子进程先于父进程终止,而父进程又没有调用wait或waitpid函数 此种情况子进程进入僵死状态,并且会一直保持下去直到系统重启.子进程处于僵死状态时,内核只保存进程的一些必要信息以备父进程所需.此时子进程始终占有着资源,同时也减少了系统可以创建的最大进程数. 僵死状态:一个已经终止.但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍占有的资源)的进程被称为

Unix环境高级编程(八)进程关系

本章看后给人似懂非懂的感觉,主要是不知道实际当中如何去使用.通过前面几章的学习,每个进程都有一个父进程,当子进程终止时,父进程得到通知并取得子进程的退出状态.先将本章基本的知识点总结如下,日后再看时候好好总结一下. 1.终端登录 介绍了有终端登录Unix系统的过程.通过init进程读文件/etc/ttys,fork一个子进程调用exec执行getty程序进行登录,当用户输入完用户名后,getty的工作完成了,然后调用login程序,类似execle("/bin/login","