进程关系

一、终端登录

1. 当系统自举时,内核创建进程 ID 为 1 的进程,也就是 init 进程。init 进程使系统进入多用户模式。init 进程根据配置文件 /etc/inittab 确定需要打开哪些终端,对每一个允许登录的终端设备,init 调用一次 fork,它所生成的子进程则执行 getty(exec)程序。(不同操作系统配置文件可能不同);

2. getty 为终端设备调用 open 函数,以读写方式将终端打开。然后 getty 输出“longin:”之类的信息,并等待用户键入用户名;

3. 当用户键入用户名后,getty 工作完成。然后调用 login 程序:execle(“/bin/login”,”login”,”-p”,username,(char *)0,envp);

4. 密码验证无误后,login 将切换目录到用户的 home 目录,改变该终端设备的权限,login 进程改变为登录用户 ID 并调用改用户的登录 shell:execl(“/bin/sh”,”-sh”,(char *)0);

5. 登录shell读取其启动文件 (Bourne shell) 和 Korn shell。从 getty 开始 exec 到 login,再 exec 到 bash,其实都是同一个进程,因此控制终端没变,文件描述符 0、1、2 也仍然指向控制终端。由于 fork 会复制 PCB 信息,所以由 Shell 启动的其它进程也都是如此。


二、网络登录
在这里插入图片描述
  当通过终端或网络登录时,我们得到了一个登录 shell,其标准输入、标准输出和标准错误要么连接一个终端设备,要么连接一个伪终端设备上。


三、进程组

#include <sys/types.h>  
#include <unistd.h>  
pid_t getpid(void); 返回:调用进程的进程 ID  
pid_t getppid(void); 返回:调用进程的父进程 ID  
uid_t getuid(void); 返回:调用进程的实际用户 ID  
uid_t geteuid(void); 返回:调用进程的有效用户 ID  
gid_t getgid(void); 返回:调用进程的实际组 ID  
gid_t getegid(void); 返回:调用进程的有效组 ID  
// 注意,这些函数都没有出错返回  

  进程组是一个或多个进程的集合。通常,它们是在同一作业中结合起来的,同一进程组中的各进程接收来自同一终端的各种信号。每个进程组有一个唯一的进程组ID。进程组 ID 类似于进程 ID — 它是一个正整数,并存放在 pid_t 数据类型中。函数 getpgrp()返回调用进程的进程组 ID

#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
pid_t getpgid(pid_t pid);
pid_t getpgrp(void);                 /* POSIX.1 version */
pid_t getpgrp(pid_t pid);            /* BSD version */
int setpgrp(void);                   /* System V version */
int setpgrp(pid_t pid, pid_t pgid);  /* BSD version */

  每个进程组有一个组长进程。组长进程的进程组 ID 等于其进程 ID。只要在某个进程组中有一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生命期。某个进程组中的最后一个进程可以终止,也可以转移到另一个进程组。进程调用 setpgid 可以加入一个现有的进程组或者创建一个新进程组


四、会话

  会话(session)是一个或多个进程组的集合
在这里插入图片描述
进程调用 setsid 函数建立一个新会话:

#include <unistd.h>
pid_t setsid(void);
// 返回值:成功返回进程组 ID;失败返回 -1

  如果调用此函数的进程不是一个进程组的组长,则此函数创建一个新会话。具体会发生以下 3 件事:

1. 该进程变成新会话的会话首进程(会话首进程是创建该会话的进程)。此时,该进程是新会话中的唯一进程;

2. 该进程成为一个新进程组的组长进程。新进程组 ID 是该调用进程的进程 ID;

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

进程调用 getsid 函数建立一个新会话:

#include <unistd.h>
pid_t getsid(pid_t pid);
// 返回值:成功返回会话首进程的进程组 ID;失败返回 -1

五、控制终端

  会话和进程组还有一些其他特性:

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

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

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

4. 如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组;

5. 无论何时键入终端的中断键(常常是 Delete 或 Ctrl+C),都会将中断信号发送至前台进程组的所有进程;

6. 无论何时键入终端的退出键(常常是 Ctrl+\),都会将退出信号发送至前台进程组的所有进程;

7. 如果终端接口检测调制解调器(或网线)已经断开连接,则将挂断信号发送至控制进程(会话首进程)。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~青萍之末~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值