在前面的章节我们了解到,进程之间是有关联的:
本章我们将了解:
?
一 终端登录(Terminal Logins)BSD Terminal Logins?BSD终端的登录程序在过去35年都没有改变。
?上面的流程如下图所示:
由init进程fork创建的进程的real user ID为0,effective user ID为0,并且他们都有超级用户权限。
程序getty的职责:为终端设备调用open函数,一旦设备被打开,文件描述符0,1,2被设置给该设备。然后getty输出一些提示符,等待我们输入用户名。当我们输入用户名后,getty的工作就完成了,然后通过调用exec函数执行登录函数,如下。
execle(“/bin/login”, “login”, “-p”, username, (char *)0, envp);
增加了login程序后,流程如下图所示:
上图中fork出来的进程都有超级用户权限,因为他们都是从init进程fork出来,而init进程有超级用户权限。
下面的进程的进程ID都是相同的,因为exec函数不改变进程的ID,并且他们的父进程的ID都是1。
现在登录程序转到login程序执行,login程序会做下面的事情:
如果我们正确登录,则login程序会继续做下面的事情:
?过程如下图所示:
我们的shell已经启动后,会去读取启动文件(.profile或.bash_profile或.bash_login或.profile,不同的系统启动文件的命名不同)。这些启动文件的作用是增加系统的环境变量,设置一些全局变量,链接等。
?
2 网络登录(Network Logins)物理登录和网络登录的区别在于:登录终端到主机的连接是否是点对点的。
网络登录情况下,登录是一种可用服务,就像其他的服务,如FTP或SMTP。
网络登录服务特点是不知道会有多少登录请求会来。所以内核不是在等待每一个可能的登录,而是通过网络接口驱动(network interface drivers)在等待一个网络连接登录请求。
为了统一处理物理登录和网络登录,一个软件驱动,叫做虚拟终端(pseudo terminal)被用来用将网络登录后的行为请求映射为真实终端的行为。
BSD Network Logins进程inetd等待处理大部分的网络连接。
下面我们将了解网络登录的过程。
启动telnetd程序的过程如下图所示:
?
telnetd进程启动后的动作为:
过程如下图所示:
?
?3 进程组(Process Groups)每一个进程都属于一个进程组。
进程组是一些进程的集合,这些进程常常关联于同一个job,并且从同一个终端接收信号。
每一个进程组都有一个唯一的进程组ID。
函数getpgrp返回调用进程的进程组ID。
函数声明:
?#include <unistd.h>
pid_t getpgrp(void);
? ? ? ? // Returns: process group ID of calling process
?
pid_t getpgid(pid_t pid);
? ? ? ? // Returns: process group ID if OK, -1 on error
函数调用getpgid(0); 和函数调用getpgrp(); 作用相同,都返回调用进程的进程组ID。
每个进程组都有个头进程,该进程的进程ID和进程组ID相同。
进程组的生命周期:从一个进程创建一个组开始,只到最有一个组内进程终止或者成为另外一个组的进程为止。
一个进程可以调用函数setpgid加入到另一个进程组或者创建一个进程组。
函数声明:
?#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
函数设置进程ID为pid的进程的进程组ID为pgid。
如果pid和pgid相同,都为某个进程的进程ID,则进程pid成为一个进程组的头进程。
如果pid为0,则表示待设置的进程为当前进程。
?
4 Sessions一个session是一个或几个进程组的集合。
例如下图所示:
一个进程通过调用函数setsid创建一个新的session。
函数声明:
?#include <unistd.h>
pid_t setsid(void);
? ? ? ? // Returns: process group ID if OK, -1 on error
如果调用进程不是组头进程,则会发生三件事:
函数getsid返回一个session leader进程的进程组ID。
函数声明:
#include <unistd.h>
pid_t getsid(pid_t pid);
? ? ? ? // Returns: session leader’s process group ID if OK, -1 on error
如果pid为0,函数getsid返回调用进程所在的session leader进程的进程组号。
?
?
参考资料:
《Advanced Programming in the UNIX Envinronment 3rd》
?
新闻热点
疑难解答