linux系统编程之进程(五) 终端、作业控制与守护进程

一、终端的概念

在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(Controlling Terminal),控制终端是保存在PCB中的信息,而我们知道fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况下(没有重定向),每个进程的标准输入、标准输出和标准错误输出都指向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器上。在控制终端输入一些特殊的控制键可以给前台进程发信号,例如Ctrl-C表示SIGINT,Ctrl-\表示SIGQUIT。

每个进程都可以通过一个特殊的设备文件/dev/tty访问它的控制终端。事实上每个终端设备都对应一个不同的设备文件,/dev/tty提供了一个通用的接口,一个进程要访问它的控制终端既可以通过/dev/tty也可以通过该终端设备所对应的设备文件来访问。ttyname函数可以由文件描述符查出对应的文件名,该文件描述符必须指向一个终端设备而不能是任意文件。在linux上的命令tty 也可以查看到当前的终端。

比如我们在图形界面下打开一个终端可能是/dev/pts/0, 第二个可能是/dev/pts/1 ...(网络终端)

而切换到字符界面下可能是/dev/tty1 ...(虚拟终端)

二、作业控制

事实上,Shell分前后台来控制的不是进程而是作业(Job)或者进程组(Process Group)。一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以同时运行一个前台作业和任意多个后台作业,这称为作业控制(JobControl)。例如用以下命令启动5个进程(这个例子出自APUE):

$ proc1 | proc2 &

$ proc3 | proc4 | proc5

其中proc1和proc2属于同一个后台进程组,proc3、proc4、proc5属于同一个前台进程组,Shell进程本身属于一个单独的进程组。这些进程组的控制终端相同,它们属于同一个Session,一个Session与一个控制终端相关。当用户在控制终端输入特殊的控制键(例如Ctrl-C)时,内核会发送相应的信号(例如SIGINT)给前台进程组的所有进程。各进程、进程组、Session的关系如下图所示。

在上面的例子中,proc3、proc4、proc5被Shell放到同一个前台进程组,其中有一个进程是该进程组的Leader,Shell调用wait等待它们运行结束。一旦它们全部运行结束,Shell就调用tcsetpgrp函数将自己提到前台继续接受命令。但是注意,如果proc3、proc4、proc5中的某个进程又fork出子进程,子进程也属于同一进程组,但是Shell并不知道子进程的存在,也不会调用wait等待它结束。换句话说,proc3 | proc4 | proc5是Shell的作业,而这个子进程不是,这是作业和进程组在概念上的区别。一旦作业运行结束,Shell就把自己提到前台,如果原来的前台进程组还存在(如果这个子进程还没终止),则它自动变成后台进程,被init进程接管。

时间: 2024-08-07 10:36:23

linux系统编程之进程(五) 终端、作业控制与守护进程的相关文章

linux系统编程基础(五) Linux进程地址空间和虚拟内存

一.虚拟内存 先来看一张图(来自<Linux内核完全剖析>),如下: 分段机制:即分成代码段,数据段,堆栈段.每个内存段都与一个特权级相关联,即0~3,0具有最高特权级(内核),3则是最低特权级(用户),每当程序试图访问(权限又分为可读.可写和可执行)一个段时,当前特权级CPL就会与段的特权级进行比较,以确定是否有权限访问.每个特权级都有自己的程序栈,当程序从一个特权级切换到另一个特权级上执行时,堆栈段也随之改换到新级别的堆栈中. 段选择符:每个段都有一个段选择符.段选择符指明段的大小.访问权

Linux系统编程---守护进程

守护进程是什么?就是在后台运行的进程. 那么如何创建守护进程呢?  1. 创建孤儿进程 2. setsid() 创建进程会话 3. 重定向标准输入, 标准输出 4. chdir, 改当当前进程的工作目录 接下来看一个例子: #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(void) { //进程成为守护进程的步骤 //代号:Ss //守护进程也称为精灵进程 //1.产生孤儿进程 pid

《Linux系统编程(第2版)》——1.4 Linux编程的概念

1.4 Linux编程的概念 本节给出了Linux系统提供的服务的简要概述.所有的UNIX系统,包括Linux,提供了共同的抽象和接口集合.实际上,UNIX本身就是由这些共性定义的,比如对文件和进程的抽象.管道和socket的管理接口等等,都构成了UNIX系统的核心. 本概述假定你对Linux环境很熟悉:会使用shell的基础命令.能够编译简单的C程序.它不是关于Linux或其编程环境的,而是关于Linux系统编程的基础. 1.4.1 文件和文件系统文件是Linux系统中最基础最重要的抽象.Li

LINUX系统编程 LINUX 虚拟内存

LINUX 虚拟内存 以32位操作系统为例子,因为64位系统虚拟地址过大为2^64,32位仅仅为2^32=4G更利于描述,但是原理东西都一样 这首先要从程序和进程之间的关系开始,我们一般写好一段C\C++代码编译后仅仅为可执行文件假设为a.out,我们 运行a.out的时候,这个才叫进程,进程是OS级别抽象的实体(PCB task_struct结构体),为程序运行进行各种检查和 系统资源分配,一个PCB包含部分信息如下: (摘至刑文鹏LINUX系统编程讲义) * 进程id.系统中每个进程有唯一的

linux系统编程之文件与I/O(六) fcntl函数与文件锁

一.fcntl函数 功能:操纵文件描述符,改变已打开的文件的属性 int fcntl(int fd, int cmd, ... /* arg */ ); cmd的取值可以如下: 复制文件描述符 F_DUPFD (long) 设置/获取文件描述符标志 F_GETFD (void) F_SETFD (long) 设置/获取文件状态标志 F_GETFL (void) F_SETFL (long) 获取/设置文件锁 F_GETLK F_SETLK,F_SETLKW 其中复制文件描述符可参见<linux系

《Linux系统编程(第2版)》——第1章 入门和基本概念 1.1 系统编程

第1章 入门和基本概念 摆在你面前的是一本关于系统编程的书,你将在本书中学习到编写系统软件的相关技术和技巧.系统软件运行在系统的底层,与内核和系统核心库进行交互.常见的系统软件包括Shell.文本编辑器.编译器.调试器.核心工具(GNU Core Utilities)以及系统守护进程.此外,网络服务.Web服务和数据库也属于系统软件的范畴.这些程序都是基于内核和C库实现的,可以称为"纯"系统软件.相对地,其他软件(如高级GUI应用),很少和底层直接交互.有些程序员一直在编写系统软件,而

《Linux系统编程(第2版)》——导读

前言 这本书是关于Linux上的系统编程."系统编程"是指编写系统软件,其代码在底层运行,直接跟内核和核心系统库对话.换句话说,本书的主题是Linux系统调用和底层函数说明,如C库定义的函数. 虽然已经有很多书探讨UNIX上的系统编程,却很少有专注于探讨Linux方面的书籍,而探讨最新版本的Linux以及Linux特有的高级接口的书籍更是凤毛麟角.此外,本书还有一个优势:我为Linux贡献了很多代码,包括内核及其上面的系统软件.实际上,本书中提到的一些系统调用和系统软件就是我实现的.因

vmware-VMware里Linux系统,键盘输入和终端输出不一样,度娘解释菜鸟看不懂,怎么解决?

问题描述 VMware里Linux系统,键盘输入和终端输出不一样,度娘解释菜鸟看不懂,怎么解决? 键盘输入方向键,终端输出ABCD,键盘输入e终端输出Tab 摁Fn+F8不管用 解决方案 VMware 里面安装个VmTools 解决方案二: 你装的时候是选择的美式键盘么?? 解决方案三: 进入 Vi 输入方向键变成 ABCD 解决方法 参考:http://blog.csdn.net/u011937547/article/details/43852913 解决方案四: 你的linux选择是美式键盘

《Linux系统编程(第2版)》——2.12 结束语

2.12 结束语 本章讨论了Linux系统编程的基础:文件I/O.在Linux这样遵循一切皆文件的操作系统中,了解如何打开.读.写和关闭文件是非常重要的.所有这些操作都是传统的UNIX方式,很多标准都涵盖它们.

《Linux系统编程(第2版)》——1.2 API和ABI

1.2 API和ABI 程序员都希望自己实现的程序能够一直运行在其声明支持的所有系统上.他们希望能在自己的Linux版本上运行的程序也能够运行于其他Linux版本,同时还可以运行在其他支持Linux体系结构的更新(或更老)的Linux版本上. 在系统层,有两组独立的影响可移植性的定义和描述.一是应用程序编程接口(Application Programming Interface,API),二是应用程序二进制接口(Application Binary Interface,ABI),它们都是用来定义