Linu系统编程---10(Linux的终端,线路规程,网络终端,进程组)
终端
输入输出设备的总称
在 UNIX 系统中,用户通过终端登录系统后得到一个 Shell 进程,这个终端成为 Shell 进程的控制终端(Controlling Terminal),
进程中,控制终端是保存在 PCB 中的信息,而 fork 会复制 PCB 中的信息,因此由 Shell 进程启动的其它 进程的控制终端也是这个终端。默认情况下(没有重定向),每个进程的标准输入、标准输出和标准错误输出都指 向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器 上。信号中还讲过,在控制终端输入一些特殊的控制键可以给前台进程发信号,例如 Ctrl-C 表示 SIGINT,Ctrl-\表示 SIGQUIT。
- Alt+Ctrl+F1、F2、F3、F4、F5、F6 字符终端 。pts(pseudoterminalslave) 指伪终端。
- Alt+F7 图形终端
- SSH、Telnet… 网络终端
终端的启动流程
文件与 I/O 中讲过,每个进程都可以通过一个特殊的设备文件/dev/tty 访问它的控制终端。事实上每个终端设 备都对应一个不同的设备文件,/dev/tty 提供了一个通用的接口,一个进程要访问它的控制终端既可以通过/dev/tty 也可以通过该终端设备所对应的设备文件来访问。ttyname 函数可以由文件描述符查出对应的文件名,该文件描述 符必须指向一个终端设备而不能是任意文件。
Linux 系统启动的终端顺序:
init–>fork–>exec–>getty–> 用户输入帐号 -->login–> 输入密码 -->exec–>bash
线路规程
线路规程就 像一个过滤器, 对于某些特殊字符并不是让它直接通过,而是做特殊处理,比如在键盘上按下 Ctrl-z,对应的字符并不会被用户程序的 read 读到,而是被线路规程截获,解释成 SIGTSTP 信号发给前台进程,通常会使该进程停止。线路规程应该过滤哪些字符和做哪些特殊处理是可以配置的。
linedisciline: 线路规程,用来过滤键盘输入的内容。
ttyname 函数
由文件描述符查出对应的文件名
char*ttyname(intfd); 成功:终端名;失败:NULL,设置 errno 下面我们借助 ttyname 函数,通过实验看一下各种不同的终端所对应的设备文件名。
#include<unistd.h>#include<stdio.h>intmain(void){printf("fd0:%s\n",ttyname(0));printf("fd1:%s\n",ttyname(1)); printf("fd2:%s\n",ttyname(2));return0;}
网络终端
虚拟终端或串口终端的数目是有限的,虚拟终端(字符控制终端)一般就是/dev/tty1∼/dev/tty6 六个,
串口终端的数 目也不超过串口的数目。然而网络终端或图形终端窗口的数目却是不受限制的,这是通过伪终端(PseudoTTY) 实现的**。一套伪终端由一个主设备(PTYMaster)和一个从设备(PTYSlave)组成**。
主设备在概念上相当于键盘和 显示器,只不过它不是真正的硬件而是一个内核模块,操作它的也不是用户而是另外一个进程。
从设备和上面介绍 的/dev/tty1 这样的终端设备模块类似,只不过它的底层驱动程序不是访问硬件而是访问主设备。
网络终端或图形终 端窗口的 Shell 进程以及它启动的其它进程都会认为自己的控制终端是伪终端从设备,例如/dev/pts/0、/dev/pts/1 等。下面以 telnet 为例说明网络登录和使用伪终端的过程。
TCP/IP 协议栈:
在数据包上添加报头。 如果telnet客户端和服务器之间的网络延迟较大, 我们会观察到按下一个键之后要过几秒钟才能回显到屏幕上。 这说明我们每按一个键 telnet 客户端都会立刻把该字符发送给服务器,然后这个字符经过伪终端主设备和从设备之后被 Shell 进程读取,同时回显到伪终端从设备,回显的字符再经过伪终端主设备、 telnetd 服务器和网络发回给 telnet 客户端,显示给用户看。其实每按一个键都要在网络上走个来回!
进程组
概念
进程组,也称之为作业。BSD 于 1980 年前后向 Unix 中增加的一个新特性。代表一个或多个进程的集合。每个 进程都属于一个进程组。在 waitpid 函数和 kill 函数的参数中都曾使用到。操作系统设计的进程组的概念,是为了简 化对多个进程的管理。
性质
- 当父进程,创建子进程的时候,默认子进程与父进程属于同一进程组。进程组 ID第一个进程 ID(组长进程)。 所以,组长进程标识:其进程组 ID其进程 ID
- 可以使用 kill-SIGKILL(9)-进程组 ID(负的)来将整个进程组内的进程全部杀死。
- 组长进程可以创建一个进程组,创建该进程组中的进程,然后终止。只要进程组中有一个进程存在,进程组就 存在,与组长进程是否终止无关。
- 进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)。
- 一个进程可以为自己或子进程设置进程组 ID
进程组操作相关函数
getpgrp 函数
获取当前进程的进程组 ID pid_t getpgrp(void);
总是返回调用者的进程组 ID
getpgid 函数
获取指定进程的进程组 ID pid_t getpgid(pid_t pid);
成功:0;失败:-1,设置 errno
如果 pid=0,那么该函数作用和 getpgrp 一样。
setpgid 函数
改变进程默认所属的进程组。通常可用来加入一个现有的进程组或创建一个新进程组。
int setpgid(pid_t pid,pid_t pgid);
成功:0;失败:-1,设置 errno 将参 1 对应的进程,加入参 2 对应的进程组中。
注意:
- 如改变子进程为新的组,应 fork 后,exec 前。
- 权级问题。非 root 进程只能改变自己创建的子进程,或有权限操作的进
练习 :修改子进程的进程组 ID,查看进程对应的进程组 ID
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(void)
{pid_t pid;if((pid = fork())< 0 ){perror("fork");exit(1);}else if(pid == 0){ printf("child PID == %d\n",getpid());printf("child Group ID == %d\n",getpgid(0));//获取自己的进程组ID //返回组
id //printf("child Group ID == %d\n",getpgrp());//返回组idsleep(7);printf("------Group ID of child is changed to %d\n",getpgid(0));}else if(pid > 0){ sleep(1);setpgid(pid,pid); //让子进程自立门户,成为进程组组长,以它的pid为进程组idsleep(13);printf("\n");printf("parent PID == %d\n",getpid());printf("parent's parent process PID == %d\n",getppid());printf("parent Group ID == %d\n",getpgid(0));sleep(5);setpgid(getpid(),getppid());//改变父进程的组id为父进程的父进程printf("\n------Group ID of parent is changeto %d\n",getpgid(0));while(1);} return 0;
}
结果:
Linu系统编程---10(Linux的终端,线路规程,网络终端,进程组)相关推荐
- alin的学习之路(Linux系统编程:五)(目录操作、进程相关概念)
alin的学习之路(Linux系统编程:五)(目录操作.进程相关概念) 1. 目录操作 1. 查看工作目录 getcwd char *getcwd(char *buf, size_t size) 功能 ...
- 【Linux | 系统编程】Linux系统编程(文件、进程线程、进程间通信)
文章目录 Linux系统编程 文件IO open/close函数 read/write函数 文件描述符 阻塞.非阻塞 fcntl函数 lseek函数 传入传出参数 文件系统 文件存储 文件操作 sta ...
- 【Linux系统编程】Linux线程浅析
00. 目录 文章目录 00. 目录 01. 进程和线程区别 02. LinuxThreads 03. NPTL 04. NGPT 05. 附录 01. 进程和线程区别 在许多经典的操作系统教科书中, ...
- 【Linux系统编程】Linux 线程浅析
进程和线程的区别与联系 在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体. 为了让进程完成一定的工作,进程必须至 ...
- 【Linux系统编程】 Linux系统调用概述
系统调用概述 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组"特殊"接口.用户程序可以通过这组"特殊"接口来获得操作系统内核提供的服务,比如用户可以 ...
- 【Linux系统编程】Linux进程管理
00. 目录 文章目录 00. 目录 01. 概述 02. 进程相关概念 03. 进程的状态 04. 进程调度 05. 程序调度函数 06. 附录 01. 概述 在Linux的内核的五大组成模块中,进 ...
- 【Linux系统编程】Linux系统调用
00. 目录 文章目录 00. 目录 01. 系统调用概述 02. 系统调用实现 03. 系统调用和库函数的区别 04. 附录 01. 系统调用概述 系统调用顾名思义,说的是操作系统提供给用户程序调用 ...
- Linux系统编程10:进程入门之系统编程中最重要的概念之进程进程的相关操作使用fork创建进程
文章目录 (1)进程的概念 (2)如何管理进程 A:描述 B:PCB C:task_struct (3)进程相关操作 A:查看进程 B:进程与父进程 (4)创建进程-fork A:fork的作用:演示 ...
- 【Linux】Linux系统编程(入门与系统编程)(三)(深入理解操作系统、进程、环境变量、内存分布)
本博客操作系统最多涉及30%的理论,重点在于部分进程的内容,部分文件系统的内容,部分文件管理的内容不是主讲操作系统,我们的最终目的是理解系统中最高频的知识点,然后被完全利用指导我们编程. 下面是这三篇 ...
最新文章
- pymysql.err.IntegrityError: (1062, Duplicate entry 'roxml-ROXML' for key 'PRIMARY')
- CV之YOLOv3:深度学习之计算机视觉神经网络Yolov3-5clessses训练自己的数据集全程记录
- Thread Safety in the Standard C++ Library
- SpringBoot中使用POI导出Excel时怎样循环数据库数据赋值
- 小肚皮最新版本_小肚皮旧版本
- 《速读ES7》新增特性目录列表
- 改动文件后缀的C语言实现
- html 滑动导航效果,jQuery实现的滑块滑动导航效果示例
- nodePPT初认识启动与手机控制
- 怎么查看自己电脑是否被安装远程监控
- MATLAB线型英文名字
- 据悉知名程序员社区因系统故障至页面乱码瘫痪,如电影情节?
- opencv检测动态物体
- 正样本/反(负)样本/易区分样本/难区分样本
- 软件需求的三个层次——业务需求、用户需求和功能需求的区别
- centos设置东八区
- Java实现swap交换函数的数组方法
- 代码随想录算法训练营第一天|704二分查找 27移除元素
- android线上内存监控_如何在Android上监控(和减少)您的数据使用情况
- percona-toolkit检查主从一致性