20201317 LYX Unix/Linux进程管理 第六周学习

第三章 Unix/Linux进程管理

本章讨论了Unix/inux 中的进程管理;阐述了多任务处理原则;介绍了进程概念;并以一个编程示例来说明多任务处理、上下文切换和进程处理的各种原则和方法。

多任务处理

​ 一般来说,多任务处理指的是同时进行几项独立活动的能力。

​ 比如,我们经常看到有人一边开车一边打电话。从某种意义上说,这些人正在进行多任务处理,尽管这样非常不好。在计算机技术中.多任务处理指的是同时执行几个独立的任务。在单处理器(单CPU)系统中,一次只能执行一个任务。

​ 多任务处理是通过在不同任务之间多路复用CPU的执行时间来实现的,即将CPU执行操作从一个任务切换到另一个任务。不同任务之间的执行切换机制称为上下文切换,将—个任务的执行环境更改为另个任务的执行环境。如果切换速度足够快,就会给人一种同时执行所有任务的错觉。这种逻辑并行性称为"并发"。在有多个CPU或处理器内核的多处理器系统中。可在不同CPU上实时、并行执行多项任务。此外,每个处理器也可以通过同时执行不同的任务来实现多任务处理。

多任务处理是所有操作系统的基础。总体上说,它也是并行编程的基础。

进程

​ 操作系统是一个多任务处理系统。在操作系统中,任务也称为进程。在实际应用中,任务和进程这两个术语可以互换使用。在中,我们把执行映像定义为包含执行代码、数据和堆栈的存储区。进程的正式定义∶进程是对映像的执行

操作系统内核将一系列执行视为使用系统资源的单一实体。系统资源包括内存空间、I/O设备以及最重要的 CPU时间。在操作系统内核中,每个进程用一个独特的数据结构表示,叫作进程控制块(PCB)或任务控制块(TCB)等。在本书中,我们直接称它为PROC 结构体。与包含某个人所有信息的个人记录一样,PROC结构体包含某个进程的所有信息。在实际操作系统中,PROC结构体可能包含许多字段,而且数量可能很庞大。

首先,我们来定义一个非常简单的PROC结构体来表示进程。

typedef etruct proc(
  struct proc *next;       // next proc pointer 
  int *ksp;                // saved sp: at byte offset 4
  int pid;                 // process ID
  int ppid;                // parent proces pid 
  int statuS;              // PROC status=FREE|READY, etc.
  int priority;            // scheduling priority 
  int kstack[1024];        // process execution stack
)PROC;
  • ksp 保存堆栈指针,以便进程恢复。当进程放弃CPU时,会将上下文保存在堆栈中。
  • pdi 进程id编号
  • ppid 父进程id编号
  • status 进程当前状态
  • priority 进程调度优先级
  • kstack[1024]进程执行时的堆栈

在PROC结构体中,next是指向下一个PROC结构体的指针,用于在各种动态数据结构(如链表和队列)中维护PROC结构体。ksp字段是保存的堆栈指针。当某进程放弃使用CPU时,它会将执行上下文保存在堆栈中,并将堆栈指针保存在PROC.ksp中,以便以后恢复。在PROC结构体的其他字段中,pid是标识一个进程的进程ID编号,ppid是父进程 ID 编号,status是进程的当前状态,priority是进程调度优先级,kstack 是进程执行时的堆栈。操作系统内核通常会在其数据区中定义有限数量的 PROC结构体,表示为∶
PROC proc [NPROC]; // NPROC a constant,e.g.64
用来表示系统中的进程。在一个单 CPU系统中,一次只能执行一个进程。操作系统内核通常会使用正在运行的或当前的全局变量PROC指针,指向当前正在执行的 PROC。在有多个CPU的多处理器操作系统中,可在不同CPU上实时、并行执行多个进程。因此,在一个多处理器系统中正在运行的[NCPU]可能是一个指针数组,每个指针指向一个正在特定CPU上运行的进程。

Unix/linux中的进程

  • INIT进程P1

    ①它是除了P0之外所有进程的祖先,所有登录进程都是它的子进程。
    ②它管理所有没有父进程的进程。(他就像孤儿院的院长,所有孤儿都叫他爸爸)。
    ③它不停寻找僵尸进程,并终止他们(埋葬它们死亡的空壳)。

操作系统启动时,内核会强行创建PID=0的初始进程,然后系统执行P0。系统挂载文件,然后初始化完成后,复刻出子进程P1。
P1运行时,执行映像更改为INIT程序,复刻出更多子进程,用于提供系统服务,这样的进程成为守护进程。

  • 进程的执行模式
  1. 中断:中断是外部设备发送给 CPU的信号,请求CPU服务。
  2. 陷阱:陷阱是错误条件,例如无效地址、非法指令、除以0等、这些错误条件被CPU识别为异常,使得CPU进入Kmode来处理错误。
  3. 系统调用:系统调用(简称syscall)是一种允许Umode 进程进入Kmode 以执行内核函数的机制。如果发生错误,外部全局变量 errno(在errno.h中)会包含一个ERROR代码,用于标识错误。用户可使用库函数perror( "error message");

进程管理中的系统调用

系统调用是什么?

简单来说,系统调用是接口,它把应用程序的请求传给内核,调用相应的内核函数完成所需的处理,再将处理结果返回给应用程序。

fork()是什么?

是创造进程的一种系统调用。

fork返回值为什么有两个?

首先fork的返回值有三种情况

返回值>0;在父进程中, fork返回新创建子进程的进程ID(进程标识符) ;
返回值=0;在子进程中, fork返回0 ;
返回值<0;如果出现错误, fork返回一个负值;

其次为什么有两个呢,是因为在执行代码:“pid = fork();”时,同时产生了一个子进程,与当前C程序完全一样的子进程,当然了,子进程中的代码段不再执行“pid = fork();”这一行了,所以这也就是为什么有两个返回值了,因为父进程和子进程各有一个返回值赋值给pid,

在执行函数fork()时,创建了一个子进程,此时是两个进程同时运行。fork()返回两次,子进程返回值为0,所以执行 printf("child pid: %d\n", getpid()); 父进程返回子进程id(pid>0),所有执行printf("pid: %d\n", pid);printf("father pid: %d\n", getpid());。两个进程执行顺序不定。

fork()的两种用法:

  1. 一个父进程希望复制自己,使父子进程同时执行不同的代码段。

比如在网络服务程序中,父进程等待客户端的服务请求。当请求到达时,父进程调用fork()使子进程处理此请求;而父进程继续等待下一个请求。

  1. 一个进程要执行一个不同的程序。

这个在shell下比较常见,这种情况下,fork()之后一般立即接exec函数。

image-20221009114555514

I/O重定向

fdt

所谓的I/O重定向也就是让已创建的FD指向其他文件。比如,下面是对STDOUT重定向到testfile.txt前后内核文件描述符表变化的示意图

在I/O重定向的过程中,不变的是FD 0/1/2代表STDIN/STDOUT/STDERR,变化的是文件描述符表中FD 0/1/2对应的具体文件,应用程序只关心前者。本质上这和接口的原理是相通的,通过一个间接层把功能的使用者和提供者解耦。

下面我们通过strace命令跟踪一下echo命令的系统调用:

image-20221009153227664

管道编程

匿名管道:一般用于父子进程
FIFO管道/命名管道:一般用于两个独立的进程

通过命令的方式实现管道:

发送文件:send.cpp

image-20221009155929625

接收文件:recv.cpp

image-20221009155959011

结果:

image-20221009160021795

通过命令行的输入实现管道的通信作用,send程序的输出变成了recv程序的输入

匿名管道:

单工管道

程序进程与Shell命令行进程单项通信

image-20221009160308497

先需要编写好发送/接收文件

先通过编码的方式实现管道

读取程序

image-20221009163739437

执行结果:

image-20221009163813923

写入程序

image-20221009163653045

结果:

image-20221009163920366

父子进程管道图解:

在这里插入图片描述

文件打开图解

在这里插入图片描述

问题与解决方案

  1. 首先是C++语言,由于是我前几次编写,没有太多经验,执行方式也遇到了困难。

解决方法:首先,我通过菜鸟教程学习了C++的简单编程,又通过其他编程语言的程序学习,成功理解了较复杂程序。

  1. 其次如何理解管道编程?

解决方法:通过查阅资料,我能很好的理解了管道的含义和理解,并通过实践进行了解决。

posted @ 2022-10-09 16:56  B1smarck  阅读(26)  评论(0编辑  收藏  举报