1、谈谈你对并⾏和并发的理解
并发是指一个处理器同时处理多个任务。并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生。
并行(Parallel),当系统有一个核以上CPU时,当一个CPU执行一个进程时,另一个CPU可以执行另一个进程,两个进程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。这就好像两个人用同一把铁锨,轮流挖坑,一小时后,两个人各挖一个小一点的坑,要想挖两个大一点得坑,一定会用多倍的时间。
2、谈谈你对⽂件描述表的理解
Linux中有一个结构体task_sturct专门用来控制进程叫做进程描述符,在它的里面存放了各种关于进程的信息,其中有一个指针,源码中给出的定义为:struct file_struct *file ,它指向一个file_struct结构体,即文件描述符表,每个进程都有一个自己的文件描述符表
我们所说的文件描述符(fd)就被写在这个file_struct之中,那么什么是文件描述符呢?
其实简单来说就是file_struct中的索引。文件描述符表的每一个表项都指向一个打开的文件,用户程序不能直接访问内核中的文件描述符表,而只能使用文件描述符表的索引 (即0、1、2、3这些数字),这些索引就称为文件描述符,用int 型变量保存。当调用open 打开一个文件或创建一个新文件时,内核分配一个文件描述符并返回给用户程序,该文件描述符表项中的指针指向新打开的文件。当读写文件时,用户程序把文件描述符传给read 或write ,内核根据文件描述符找到相应的表项,再通过表项中的指针找到相应的文件。每一个程序打开的时候都会自动打开文件描述符表中的0,1,2,他们分别是标准输入,标准输出和标准错误。
默认情况下(没有重定向),每个进程的标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)都指向控制终端,因为在程序启动时(在main 函数还 没开始执行之前)会自动把控制终端打开三次,分别赋给三个FILE *指 针stdin 、stdout和stderr,这三个文件指针是libc 中定义的全局变量,这三个文件的描述符分别是0、1、2,保存在相应的FILE 结构体中。进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器上。
3、谈谈你对PCB(进程控制块)的理解
操作系统负责管理所有进程,包括进程的创建和消亡、进程状态的转换以及分配和回收进程所需要的资源等等。操作系统管理和控制进程的过程,全部要借助进程控制块才能完成。
操作系统创建每个进程时,都会额外申请一块内存空间,用来存储、管理和控制该进程所需要的信息,例如:
- 进程名称或者 ID 号,作为该进程的标识;
- 当前进程的执行状态,进程在整个执行过程中可能处于开始、就绪、运行、等待或者终止这 5 种状态;
- 进程占用的各种资源,例如内存大小、使用的输入输出设备等等。
- 还记录了进程已经执行的时间,占用 CPU 的时间等等。
我们通常将这样的存储空间称为进程
控制块(Process Control Block,简称 PCB)。
也就是说,进程控制块记录了进程当前运行情况以及所占资源的详细信息,并由操作系统负责管理和维护。操作系统中进程和进程控制块的数量始终是相等的,创建多少个进程就会相应产生多少个进程控制块。
进程控制块是进程存在的唯一标识,只有借助进程控制块,操作系统才能找到目标进程,进而实施管理和控制。当进程执行结束后,操作系统只需要释放相应进程控制块占用的内存空间,目标进程也随之消亡。