您的位置:首页 > 编程语言

UNIX环境高级编程 第9章 进程关系

2017-05-02 10:36 344 查看
在第8章学习了进程的控制原语,通过各种进程原语可以对进程进行控制,包括新建进程、执行新程序、终止进程等。在使用fork( )产生新进程后,就出现了进程父子进程的概念,这是进程间的关系。本章更加详细地说明进程间的关系,包括:进程组、会话、作业等。

终端登录

当我们通过硬件终端而非网络终端登录到系统时,UNIX会有一个登录流程,该流程是个大概的过程,各个实现可能存在细微差别,但总体流程不变。

在通过终端登录时,init进程负责为每个终端fork一个子进程,由子进程对应登录终端设备。init进程会fork一份副本init,然后exec加载一个程序,该程序负责打开终端设备,后续用户通过该终端设备来与系统交互。当exec加载一个程序并打开终端之后,该程序提示用户输入用户名,之后再exec或者fork子进程来加载login程序进行登录,login程序负责验证密码,并通过读取配置文件来初始化用户终端环境。

网络登录

网络登录和终端不太相同,网络登录的需求衍生了伪终端,关于通过伪终端的登录将会在第19章说明。

进程组

每个进程都有一个进程ID。另外,每个进程都属于一个进程组。进程组是一个进程或多个进程的集合。和进程ID类似,每个进程组都有一个进程组ID,进程组ID等于组长进程ID,然而组长进程不一定会一直存在,组长进程可能在创建进程组之后结束,但组长进程结束之后,进程组依旧存在,此时没了组长。进程组的生命周期是从进程组创建开始,一直到最后一个组员离开。最后一个组员离开的方式有两种:一是组员结束死亡,二是组员脱离进程组,加入到它人的进程组。

UNIX提供了两个接口可以用于返回进程组的ID,还提供了一个创建或者加入别的进程组的接口,其头文件及函数原型如下:

#include <unistd.h>

pid_t getpgrp (void);

pid_t getpgid (pid_t pid);

int setpgid (pid_t pid, pid_t pgid);


对于第一个函数没有出错返回,其返回值是调用进程的进程组ID;

对于第二个函数,当参数为0时,成功则返回进程组ID,出错则返回-1。

对于第三个函数,成功时返回0,出错返回-1。

一个进程只能为自己或者它的子进程设置进程组ID,但子进程调用exec之后,执行了新程序,父进程就不能再为子进程设置进程组ID,因为exec执行的新程序可能与父进程再无任何关系。

会话

会话是一个或多个进程组的集合。通常是有shell将多个进程组成一个会话。进程也可以通过UNIX提供的接口来主动创建一个新会话。其头文件及函数原型如下:

#include <unistd.h>

pid_t setsid (void);


该函数成功是返回0,失败返回-1。

调用该函数的进程不能是一个进程组的组长,否则会失败。如果不是进程组组长,则该调用会创建一个新会话,并且调用进程称为会话leader,同时该调用会成为一个创建一个新进程组,并成为该新进程组的组长,最后该进程的会失去终端。

控制终端

一个会话最多只有一个控制终端,也允许没有终端。一个会话中的进程组可以被分为前台进程组以及一或多个后台进程组。如果会话有控制终端,那么该会话中就分为前台进程和后台进程,对终端的一些操作而引发的信号会发送到前端进程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: