第九章 进程关系
一:主要内容:
进程之间具有关系,每个进程都会有一个父进程,当子进程退出时,父进程可以得到通知并能取得子进程的退出状态。
二:终端登录
对于BSD终端登录,当系统自举时(不清楚什么时自举),内核会创建ID为1的进程,也就是init进程。init进程使系统进入多用户模式,init读取文件/etc/ttys,对每一个允许登录的终端设备,init调用一次fork,他所生成的子进程则exec getty程序。流程如下图
上图中创建出来的所有用的实际ID和有效ID都是0。getty对终端设备用open函数,以读、写方式将终端打开。之后getty程序会打出login提示信息,用户输入了用户名称,然后调用getpwnam取得相应用户的口令文件登陆项。然后调用getpass(3)以显示密码提示信息,之后用户输入密码,调用crypt(3)加密密码,然后与阴影文件中的pw_passwd字段进行对比,多次不匹配则登陆失败。
现在系统的用户身份验证过程已经发展到了支持多个身份验证过程,统称为PAM。如果应用程序需要验证用户是否具有适当的权限去执行某个服务,可以使用PAM来进行验证。
如果用户登陆成功,login将完成如下操作:
至此,登录用户的登录shell开始运行。其父进程ID是init进程。当该shell终止时,init进程会受到信号,然后对终端重复全部上述过程。
对于其他的系统的登录过程实际上都大同小异,不详细介绍了。
三:网络登录
网络登录和终端登录最主要的区别就是网络的登录在计算机和终端之间的连接不再是点到点的。在网络登录中,login仅是一种可用的服务。
为使一个软件既能处理终端登录,也能处理网络登录,系统使用了一种伪终端的软件驱动程序。在系统启动的时候,init调用一个shell,执行脚本/etc/rc,这个脚本会启动一个守护进程inetd。inetd会等待每一个TCP/IP连接,一旦有连接过来,他就会执行一个fork,生成的子进程调用exec来处理请求。
四:进程组
每一个进程除了有一个进程ID之外,还会属于一个进程组,一个进程组是多个进程的集合。每一个进程组也会有一个唯一的进程组ID,是一个正整数,可以存放在pid_t数据类型中,函数getpgrp返回调用进程的进程组ID。
每个进程组会有一个小组长,这个组长进程的ID等于进程组ID,这个比较好理解,组长的角色可以,进程组组长可以创建进程并且终结自身,一个组长的消亡不代表这个进程组也不存在了,只有进程组内的进程都没有了,这个进程组才没有了。