第九章-进程关系

一、终端登录

1. BSD终端登录

系统管理者通常创建 /etc/ttys 文件,其中每一行代表一个终端设备,说明设备名和传到getty程序的参数。
系统自举时,首先创建进程ID为1的进程,即init进程。init进程使系统进入多用户模式。init读取文件/etc/ttys,对每一个允许登录的终端设备,init调用一次fork,生成的子进程则exec getty程序。
在这里插入图片描述
当用户键入了用户名后,getty的工作就完成了。然后它以类似于下列的方式调用login程序:

execle("bin/login", "login", "-p", username, (char*)0, evnp);

因为最初的init进程具有root权限,所以图中所有进程都有root权限。
login能调用getpwnam取得相应用户的口令文件登录项,然后调用getpass提示、获取密码。

二、网络登录

与终端登录的区别是:网络登录时,在终端和计算机之间的连接不再是点到点的。login仅是一种可用的服务,与其他网络服务(如FTP或SMTP)性质相同。

终端登录中,init知道哪些终端设备可用来登录,并为每个设备生成一个getty进程。在网络登录中,所有登录都经由内核的网络接口驱动程序,而且事先不会知道有多少这样的登录。因此必须等待一个网络连接请求的到达,而不是使一个进程等待每一个可能的登录。

1.BSD网络登录

在BSD中,有一个inetd进程(因特网超级服务器),它等待大多数网络连接。init调用shell执行脚本/etc/rc,由此脚本启动一个守护进程inetd。shell脚本终止后,inetd的父进程就变成init。inetd等待TCP/IP连接到达,一个请求到达则执行一次fork,然后生成的子进程exec适当的程序。

假定一个对于TELNET(使用TCP协议的远程登录应用程序)服务进程的TCP/IP连接请求到达。

# telnet hostname

该客户进程打开一个到hostname主机的TCP连接,在hostname主机上启动的程序被称为TELNET服务进程。然后,客户进程和服务进程之间使用TELNET应用协议通过TCP连接交换数据。
在这里插入图片描述
然后telnetd进程打开一个伪终端设备,并用fork分为两个进程。父进程处理通过网络连接的通信,子进程则执行login程序,父进程和子进程通过伪终端想连接。在调用exec之前,子进程使其文件描述符0、1、2与伪终端相连。
在这里插入图片描述

2. Linux网络登录

除了有些版本使用扩展的守护进程xinetd(提供更精细的控制)代替inetd以外,其他方面相同。

三、进程组

进程组是一个或多个进程的集合,通常,他们是在同一个作业中结合起来的,同一进程组中的各进程接收来自同一终端的各种信号:

#include <unistd.h>
pid_t getpgrp(void);
pid_t getpgid(pid_t pid);

getpgrp返回调用线程的进程组ID,getpgid返回pid进程的进程组ID。
所以 getpgid(0)等价于getpgrp();
每个进程组都有一个组长进程,组长进程的进程组ID等于其进程ID。
进程调用setpgid可以加入一个现有的进程组或者创建一个新进程组:

#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);

将pid进程的进程组ID设为pgid

四、会话

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

#include <unistd.h>
pid_t setsid(void);

成功,返回进程组ID;出错,返回-1。

  • 如果该调用进程不是一个进程组的组长,则此函数创建一个新会话。并且:
    (1)该进程变成新会话的会话首进程(session leader)。
    (2)该进程成为一个新进程组的组长进程。进程组ID是该调用进程的进程ID。
    (3)该进程没有控制终端。若调用setsid之前已经有一个控制终端,则切断。
  • 如果该调用进程一个进程组的组长,则此函数返回出错。为了避免这种情况,通常先调用fork,然后使其父进程终止,子进程继续。

五、终端控制

会话和进程组的其他特性

  • 一个会话可以有一个控制终端(controlling ternimal)。通常是终端设备(终端登录时)或伪终端设备(网络登录时)。
  • 建立与控制终端连接的首进程被称为控制进程
  • 一个会话中的几个进程组可被分为一个前台进程组和若干个后台进程组
  • 如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组
  • 无论何时键入终端的中断键(通常是Ctrl+C)或退出键(通常是Ctrl+\),都会将中断信号或退出信号发送至前台进程组的所有进程
  • 若终端接口检测到断开,则将挂断信号发送至控制进程(会话首进程)
    如图:
    在这里插入图片描述
    通常,登录时,将自动建立控制终端

六、函数tcgetpgrp、tcsetpgrp和tcgetsid

需要一种方法来通知内核哪一个进程组是前台进程组,这样,终端设备驱动程序就能知道将终端输入和终端产生的信号发送到何处。

#include <unistd.h>
pid_t tcgetpgrp(int fd); //成功,返回前台进程组ID;出错,返回-1
int tcsetpgrp(int fd, pid_t pgrpid); //成功,返回0;出错,返回-1

fd是会话的控制终端。tcsetpgrp将pgrp设为前台进程组。

七、作业控制

八、shell执行程序

九、孤儿进程组

一个其父进程已终止的进程称为孤儿进程,这种进程由init进程“收养”。整个进程组也可称为“孤儿”。

十、FreeBSD实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值