码迷,mamicode.com
首页 > 系统相关 > 详细

读书笔记-APUE第三版-(9)进程关系

时间:2015-07-30 23:32:09      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:apue   操作系统   linux   

登录过程


终端登录

init从/etc/ttys中读取终端信息,对每个允许登录的终端,都fork子进程,并执行getty。getty打开终端设备,执行login:

execle(“/bin/login,“login”, “-p”, username, (char *)0, envp)
技术分享

 

login进行用户名密码验证,同时还会进行切换到用户主目录/修改终端设备属主&读写权限/创建进程组/setuid等动作,然后运行login shell。          

 execl(“/bin/sh”,“-sh”, (char*)0)

技术分享

Login shell的标准输入、输出和错误输出都被设置为终端设备,login shell还会读取.bash_profile等初始化文件

网络登录

通过网络登录的最大不同是,终端和主机之间的连接不是点对点的。和FTP和SMTP等网络服务一样,网络登录也只不过是一种服务。

技术分享

如图,系统通过inetd(xinetd)守护进程处理网络连接。假设用户在其他主机运行

telnet hostname
inetd 根据网络连接类型fork出子进程运行相应的telnetd程序。Telnetd会开启伪终端,并进行fork。父进程处理网络通信,子进程运行login程序,接下来流程和上一节介绍的通过终端登录一致。(伪终端和实际用户终端之间的通信细节后续章节介绍)

进程组

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

进程组是一组进程的集合。进程通过调用setpgid方法创建或者加入进程组。如果进程ID和进程组ID相等,该进程被称之为组长(leader)。进程组的生命周期开始于创建,结束于组内最后一个进程终止(组长可能先挂掉没有关系)。在shell的作业控制过程中,父进程fork子进程后,都会调用setpgid方法,确保子进程加入进程组。

会话

会话是一组进程组的集合。如下图,会话中的进程组布局一般由shell管道产生:

proc1|proc2 & proc3|proc4|proc5

技术分享

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

进程调用setsid创建会话,该进程成为会话组长,同时创建了一个新的进程组,调用进程成为进程组组长。已经是进程组组长的进程调用setsid会失败,所以常见处理方式是父进程fork出子进程之后终止,让子进程创建会话,因为子进程的进程组ID继承自父进程,所以必定还不是组长。

控制终端

一个会话只能有一个控制终端。与控制终端建立连接的会话组长,称之为控制进程。前台进程组即拥有控制终端的进程组,中断信号(Control+C)会发送给前台进程组中的所有进程。

技术分享


include <unistd.h> 45
pid_t tcgetpgrp(int filedes);
int tcsetpgrp(int filedes, pid_t pgrpid)

通过tcgetpgrp和tcsetpgrp可以获取和设置前台进程组。只有拥有控制终端的进程才能调用tcsetpgrp方法。这两个方法一般用于作业控制而不会被应用程序程序直接调用。

作业控制

一个作业(job)一般来讲是一组进程通过管道连接组成的进程组。命令行后加上&启动的就是后台作业。键入Ctrl+Z,发送SIGTSTP信号,可以将前台作业暂停并转为后台。只有前台作业能接收终端输入,后台作业试图读取终端输入时,终端驱动会发送SIGTTIN信号给后台作业,后台作业暂停,并在标准输出上报告作业状态。在mac上试了一把,输入fg视图让后台作业转为前台,挂了。。据说这是mac的bug。而后台作业输出到终端是没有问题的,但可以通过stty tostop命令禁止输出。

技术分享

下图总结了会话中前台进程组、后台进程组和终端之间的交互关系。其中SIGTTOU信号发生于后台进程组想要进行输出时。

技术分享

Shell运行程序

实验一下shell执行程序时和进程租,控制终端、会话和作业控制等概念的对应关系。

Mac不太灵,这次来看看Linux,首先是管道:

技术分享

三个进程都属于同一个会话(26071);ps和cat都是bash(28629)的子进程,属于同一个前台进程组(17121),拥有控制终端,ps是组长;而bash单独属于一个进程组(28629)。

再试试后台作业:

技术分享

最大的区别是拥有控制终端的前台进程组变为bash所在组。

最后验证一下连续管道,看来bash fork出了三个子进程。

技术分享

孤儿进程组

当进程组中所有成员的父进程要么在该组中,要么不属于这个会话时(父进程提前挂掉的子进程会被init“收养”),这个进程组被称为孤儿进程组。系统将给孤儿进程组发送SIGHUP(默认行为是终止进程)和SIGCONT(继续运行)信号。

           

版权声明:本文为博主原创文章,未经博主允许不得转载。

读书笔记-APUE第三版-(9)进程关系

标签:apue   操作系统   linux   

原文地址:http://blog.csdn.net/idontwantobe/article/details/47156213

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!