操作系统面试习题(上)
操作系统面试习题
1,什么是操作系统吧!
操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是计算机的基石。
操作系统本质上是一个运行在计算机上的软件程序,用于管理计算机硬件和软件资源。
操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。 内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。
速记
操作系统简称OS,软硬资源它来管。
软件程序是本质,计算机里作基石。
内核核心很关键,内存设备都照管。
文件应用它统筹,桥梁作用稳又全。
2,什么是系统调用呢?
系统调用是指由操作系统实现提供的所有系统调用所构成的集合,即程序接口或应用编程接口。系统调用把应用程序的请求传给内核,调用相应的内核函数完成所需的处理,将处理结果返回给应用程序。这样可以实现从用户态到核心态的转变,完成特定的功能,是应用程序和操作系统之间的桥梁。
根据进程访问资源的特点,我们可以把进程在系统上的运行分为两个级别:
用户态(user mode) : 用户态运行的进程可以直接读取用户程序的数据。
系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。
这些系统调用按功能大致可分为如下几类:
设备管理。完成设备的请求或释放,以及设备启动等功能。
文件管理。完成文件的读、写、创建及删除等功能。
进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
进程通信。完成进程之间的消息传递或信号传递等功能。
内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。
速记
系统调用集合妙,程序接口真可靠。
应用请求内核跑,处理结果反馈好。
用户核心状态跳,桥梁作用真重要。
进程运行分两级,用户系统各有招。
用户态读数据巧,系统态访资源豪。
系统调用功能高,设备文件管得牢。
进程控制又通信,内存管理没烦恼。
3,简述Linux系统态与用户态,什么时候会进入系统态?
为什么区分内核态与用户态:在 CPU 的所有指令中,有一些指令是非常 危险 的,如果 错用,将导致整个系统 崩溃。比如:清内存、设置时钟 等。所以区分 内核态 与 用户态 主要是出于 安全 的考虑。
Linux 系统的运行状态可以分为系统态(内核态)和用户态(用户态)两种。
系统态 也被称为 内核态,它拥有系统的 完全访问权限,可以访问所有的 硬件资源,执行所有 特权操作,例如 读写系统内存、读写硬件设备 等。与此相反,用户态 也被称为 用户空间 或 用户态,它只能访问用户自己的 程序 和 数据,不能直接访问 系统硬件资源,如果要访问 硬件资源,必须通过 系统调用 进行。
进入内核态:共有三种方式:a、系统调用。b、异常。c、设备中断。其中,系统调用 是 主动 的,另外两种是 被动 的。
在 Linux 中,当 应用程序 执行一些 系统调用 时,会从 用户态 切换到 系统态。例如,当 应用程序 需要访问 文件系统、网络资源 或其他 系统资源 时,就会调用相应的 系统函数,这些 系统函数 需要使用 系统态权限 才能完成操作。因此,在这种情况下,应用程序 会从 用户态 切换到 系统态。
此外,当 应用程序 执行一些需要 特权操作 的 系统调用 时,也会从 用户态 切换到 系统态。例如,当 应用程序 需要 创建 或 删除文件、修改文件权限、修改网络连接 等操作时,就需要使用 系统态权限 来完成。因此,在这种情况下,应用程序 也会从 用户态 切换到 系统态。
总之,在 Linux 中,当 应用程序 需要进行一些需要 特权操作 或访问 系统资源 的操作时,就需要从 用户态 切换到 系统态。
速记
内核用户态分家,危险指令防乱抓。清存设钟易垮塌,安全考量为大家。
Linux系统分两家,内核特权资源拿。用户受限范围狭,系统调用把桥搭。
进入内核有三叉,系统调用主动发。异常中断被动达,特权操作切换佳。
3,简述系统调用的过程?
系统调用是操作系统提供给用户程序的一组接口,用于访问操作系统的功能。当用户程序需要访问操作系统的功能时,它会通过系统调用接口来请求操作系统提供相应的服务。
系统调用的过程通常包括以下几个步骤:
- 用户程序:用户程序通过系统调用接口向操作系统发出请求,请求执行特定的操作。
- 系统调用:操作系统接收到用户程序的请求后,会执行相应的系统调用处理程序。
- 参数传递:系统调用处理程序会将用户程序传递的参数保存到内核栈中。
- 系统调用处理程序:系统调用处理程序会根据用户程序的请求,执行相应的操作。
- 返回结果:系统调用处理程序会将操作的结果返回给用户程序。
- 用户程序:用户程序接收到系统调用处理程序返回的结果后,继续执行。
速记
系统调用给接口,用户访问功能求。
需求发出接口走,系统接收处理有。
参数传递内核留,对应操作跟着瞅。
处理完毕结果丢,用户接着继续溜。
进程、线程与协程
4,进程和线程以及协程的区别
进程:程序 是 指令、数据 及其 组织形式 的描述,而 进程 则是 程序 的 运行实例,包括 程序计数器、寄存器 和 变量 的 当前值。
线程:微进程,一个 进程 里更小 粒度 的 执行单元。一个 进程 里包含多个 线程 并发执行 任务。
协程:协程 是 微线程,在 子程序 内部执行,可在 子程序 内部 中断,转而执行别的 子程序,在适当的时候再返回来接着执行。
区别:
线程 与 进程 的 区别:
(1)一个 线程 从属于一个 进程;一个 进程 可以包含多个 线程。
(2)一个 线程 挂掉,对应的 进程 挂掉;一个 进程 挂掉,不会影响其他 进程。
(3)进程 是 系统资源调度 的 最小单位;线程 是 CPU 调度 的 最小单位。
(4)进程 的 系统开销 显著大于 线程开销;线程 需要的 系统资源 更少。
(5)进程 在执行时拥有 独立的内存单元,多个 线程 共享 进程 的 内存,如 代码段、数据段、扩展段;但每个 线程 拥有自己的 栈段 和 寄存器组。
(6)进程切换 时需要 刷新 TLB 并获取新的 地址空间,然后切换 硬件上下文 和 内核栈,线程切换 时只需要切换 硬件上下文 和 内核栈。
(7)通信方式 不一样。
(8)进程 适应于 多核、多机分布;线程 适用于 多核。
线程 与 协程 的 区别:
(1)协程执行效率 极高。协程 直接操作 栈 基本没有 内核切换 的 开销,所以 上下文的切换 非常快,切换开销 比 线程 更小。
(2)协程 不需要 多线程 的 锁机制,因为多个 协程 从属于一个 线程,不存在同时写 变量 冲突,效率 比 线程 高。
(3)一个 线程 可以有多个 协程。
速记
程序描述进程现,计数寄存变量全。 进程之内线程转,更小粒度任务干。 协程微线本领显,子程中断再续缘。
线程进程关系妙,线程从属进程跑。 线程挂掉进程倒,进程之间互不扰。 资源调度进程搞,CPU 调线程巧。 进程开销真是高,线程资源用得少。 进程内存独自要,线程共享乐逍遥。 切换进程事不少,线程切换简单搞。 通信方式各有道,多核分布看需要。
协程效率真叫高,操作栈上开销少。 内核切换它不要,上下切换快如飙。 多线锁机用不着,同线协程没烦恼。 变量冲突不来找,执行效率呱呱叫。 一线能把多协包,协同工作真奇妙。
5,一个进程可以创建多少线程,和什么有关?
一个进程可以创建的线程数量主要取决于以下因素:
- 系统资源和硬件性能:一个进程所能创建的线程数量受到系统资源和计算机硬件性能的限制。这包括CPU、内存、硬盘和网络等资源。例如,操作系统可能会限制每个进程的虚拟内存使用量,这会影响可以创建的线程数量。此外,计算机的核心数量和内存容量也会影响线程的创建数量。
- 线程类型:线程可以分为内核线程和用户线程。内核线程是由操作系统管理的,其数量通常受到操作系统和计算机硬件的限制。而用户线程是由用户自己管理的,其数量通常受到操作系统对每个进程的线程数量限制的影响。
- 线程使用方式:线程的使用方式也会影响进程可以创建的线程数量。例如,一个进程可能需要基于进程的线程来完成特定任务,这种情况下,线程的数量可能不会受到系统资源的限制,但会受到操作系统对每个进程的线程数量限制的影响。
速记
线程创建有限制,资源硬件来管制。CPU内存和网络,虚拟内存也有尺。
线程类型分两种,内核用户各不同。前者系统来管理,后者用户自操控。
使用方式有影响,任务需求要细想。系统限制心中记,线程数量才稳当。
有了进程为什么还需要线程?
进程是程序的动态表现,它可以独立地执行任务,拥有自己的内存空间和系统资源。而线程则是进程中的执行单元,多个线程共享同一个进程的资源(如内存空间、文件等)。
- 资源占用:进程需要占用更多的系统资源,包括内存空间、文件句柄等。而线程只需要占用较少的系统资源,包括栈空间、寄存器等。
- 切换成本:进程切换需要保存和恢复所有的寄存器和内存状态,这需要花费较多的时间和计算资源。而线程切换只需要保存和恢复寄存器状态,这需要花费较少的时间和计算资源。
- 并发性:进程之间是相互独立的,它们之间的并发性比较差。而线程之间是共享同一个进程的资源,它们之间的并发性比较好。
- 通信成本:进程之间的通信需要使用进程间通信机制,如管道、消息队列等。而线程之间的通信可以直接访问共享变量,这需要花费较少的时间和计算资源。
- 编程复杂度:进程之间的编程复杂度比较高,需要使用进程间通信机制。而线程之间的编程复杂度比较低,不需要使用进程间通信机制。
因此,进程和线程之间存在一些区别,但是它们都有各自的优点和缺点。在实际应用中,需要根据具体的需求来选择使用进程还是线程。
速记
进程动态任务跑,内存资源自己搞。 线程本是进程胞,共享资源效率高。 资源占用有分晓,进程多来线程少。 切换成本大不同,进程繁琐线程巧。 并发程度也重要,进程独立线程好。 通信成本差不少,进程复杂线程妙。 编程难度有低高,按需选用错不了。
为什么要用多线程
多线程是一种并发编程技术,它可以提高程序的执行效率和响应速度。 以下是一些使用多线程的原因:
- 提高程序的执行效率:多线程可以同时执行多个任务,从而提高程序的执行效率。例如,在一个程序中,可以使用多线程来处理多个文件的读取和写入操作,从而提高程序的执行效率。
- 提高程序的响应速度:多线程可以使程序的响应速度更快。例如,在一个程序中,可以使用多线程来处理用户的输入和输出操作,从而提高程序的响应速度。
- 简化程序的设计:多线程可以简化程序的设计。例如,在一个程序中,可以使用多线程来处理多个任务,从而简化程序的设计。
- 提高程序的可扩展性:多线程可以提高程序的可扩展性。例如,在一个程序中,可以使用多线程来处理多个任务,从而提高程序的可扩展性。
- 提高程序的可靠性:多线程可以提高程序的可靠性。例如,在一个程序中,可以使用多线程来处理多个任务,从而提高程序的可靠性。
速记
多线并发编程妙,效率响应都提高。
同时处理多任务,执行加速没烦恼。
用户输入输出搞,响应速度快如飙。
程序设计变轻巧,多个任务轻松搞。
扩展可靠都不少,多线优势真奇妙。
6,进程有哪几种状态?
在操作系统中,进程通常有五种状态,包括 创建、就绪、运行(执行)、终止和阻塞。
- 创建状态:进程正在 创建或初始化,获取进程管理块 PCB。
- 就绪状态:进程已经 具备了运行条件,等待系统分配处理器 以便运行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态,获取处理器资源。
- 运行状态:进程正在 CPU 上运行,分配时间片运行,使用完进入就绪状态。
- 阻塞状态:进程正在 等待某一事件 而暂停运行,比如 等待某资源为可用或等待 I/O 完成。即使 CPU 空闲,该进程也不能运行。等待被分配处理器资源,以及 时间片进入运行状态
- 终止状态:进程 已经结束。
进程的状态转换 通常是基于 等待某些条件的发生,例如 等待 I/O 操作的完成或等待其他资源变得可用 等等。这些 状态转换通常由操作系统内核来处理和协调。
速记
进程状态有五种,创建就绪与运行。阻塞终止要记清,状态转换有章程。
创建初始拿PCB,就绪等待资源齐。运行之时占CPU,时间片完回就绪。
阻塞等待事来临,资源IO要搞定。终止状态进程停,内核协调转不停。
7,进程状态的切换你知道多少?
主要是三种状态之间的切换
就绪状态(ready): 等待被调度
运行状态(running)
阻塞状态(waiting): 等待资源
应该注意以下内容:
只有 就绪态和运行态 可以相互转换,其它的都是 单向转换。就绪状态的进程通过调度算法从而获得 CPU 时间,转为运行状态; 而 运行状态的进程,在分配给它的 CPU 时间片用完之后 就会转为就绪状态,等待下一次调度。
阻塞状态是缺少需要的资源从而由运行状态转换而来,但是该资源不包括 CPU 时间,缺少 CPU 时间会从运行态转换为就绪态。
速记
进程状态三切换,就绪运行与阻塞。
就绪等待被调度,运行之中占CPU。
阻塞缺资源来靠,状态转换有诀窍。
就绪运行互转换,调度分片来回转。
运行若缺CPU片,转回就绪再候遣。
资源不足阻塞现,运行单向此路专。
进程与线程通信方式
8,进程间的通信常见的的有哪几种方式呢?
进程间通信(Inter-Process Communication,IPC)是指在不同进程之间传递数据或信号,以实现协同工作。常见的进程间通信方式主要包括以下几种:
(1). 管道(Pipe)
- 匿名管道(Anonymous Pipe)
- 特点:半双工通信,数据只能单向流动;只能在具有亲缘关系的进程间使用(如父子进程)。
- 示例:在Shell中通过
|连接命令(如ls | grep txt),就是利用匿名管道将ls的输出传递给grep。
- 命名管道(Named Pipe,FIFO)
- 特点:全双工通信(实际仍需通过读写端实现);允许无亲缘关系的进程通信;通过文件系统中的特殊文件标识。
- 示例:两个进程通过
mkfifo创建的管道文件进行通信。
(2). 消息队列(Message Queue)
- 特点:消息的链表,存储在内核中;消息有类型标识,接收方可按类型接收;克服了管道无格式的字节流限制。
- 示例:生产者进程发送不同类型(如订单、物流)的消息,消费者进程按需接收特定类型的消息。
(3). 共享内存(Shared Memory)
- 特点:多个进程映射同一块物理内存,直接读写该区域,无需内核介入,通信效率最高;但需同步机制(如信号量)避免竞争。
- 示例:两个进程共享一个数组,一个进程写入数据,另一个进程读取。
(4). 信号量(Semaphore)
- 特点:用于进程同步,通过计数器控制对共享资源的访问;可实现互斥(如二值信号量)或资源计数(如多进程并发访问)。
- 示例:多个进程通过信号量协调对共享内存的访问,避免数据冲突。
(5). 信号(Signal)
- 特点:用于通知进程某个事件发生(如
SIGINT中断信号);信号处理简单,但信息量有限。 - 示例:用户按下
Ctrl+C,Shell向进程发送SIGINT信号,终止进程。
(6). 套接字(Socket)
- 特点:支持跨网络通信,也可用于本地进程间通信;提供全双工、可靠的通信。
- 示例:Web服务器与客户端通过TCP套接字通信;本地进程通过
AF_UNIX套接字通信。
(7). 信号集(Signal Set)与信号驱动(Signal-Driven IPC)
- 特点:通过信号集批量处理信号,结合
sigaction实现更复杂的信号处理逻辑。 - 示例:进程注册多个信号的处理函数,通过信号集统一处理。
(8). 文件映射(Memory-Mapped Files)
- 特点:将文件映射到进程的地址空间,多个进程可共享访问;适用于大文件或需要持久化的共享数据。
- 示例:数据库系统通过内存映射文件实现高效的数据读写。
(9). 远程过程调用(RPC)
- 特点:隐藏底层通信细节,使远程调用像本地调用一样简单;适用于分布式系统。
- 示例:客户端调用远程服务器的函数,RPC框架负责参数序列化、网络传输和结果返回。
(10). 消息传递(Message Passing)
- 特点:通过内核或中间件传递结构化消息;支持同步/异步、阻塞/非阻塞模式。
- 示例:微服务架构中,服务间通过消息队列(如RabbitMQ)传递请求和响应。
速记
进程通信方式妙,管道消息不能少。
匿名管道单向跑,亲缘进程才能搞。
命名管道全双到,无关进程也能聊。
消息队列内核保,类型标识接收巧。
共享内存效率高,同步机制要抓牢。
信号量来管同步,信号通知事来到。
套接字通网络妙,本地通信也可靠。
信号集合批量搞,文件映射持久好。
RPC调像自找,消息传递架构妙。
PCB指的是什么
PCB(Process Control Block)是操作系统中用于管理进程的一种数据结构。它包含了进程的各种信息,如 进程标识符(PID)、进程状态、进程优先级、进程的程序计数器、寄存器值、内存管理信息、文件描述符表 等。PCB是操作系统中管理进程的基本单位,它是进程存在的前提。
PCB的主要作用包括:
- 进程管理:PCB用于管理进程的状态、优先级、资源分配等信息,操作系统通过PCB来控制和调度进程的执行。
- 进程切换:当一个进程被切换到运行状态时,操作系统需要保存当前进程的上下文信息(如寄存器值、程序计数器等),并加载新进程的上下文信息。PCB就包含了这些信息,以便在进程切换时恢复进程的执行。
- 进程同步:PCB还包含了用于进程同步的信号量、事件等信息,这些信息用于实现进程间的同步和通信。
- 进程通信:PCB还包含了用于进程通信的消息队列、共享内存等信息,这些信息用于实现进程间的通信。
- 进程资源管理:PCB还包含了用于进程资源管理的内存管理信息、文件描述符表等信息,这些信息用于管理进程的资源。
PCB是操作系统中管理进程的基本单位,它是进程存在的前提。它包含了进程的各种信息,如 进程标识符、进程状态、进程优先级、进程的程序计数器、寄存器值、内存管理信息、文件描述符表 等。PCB的主要作用包括进程管理、进程切换、进程同步、进程通信和进程资源管理等。
速记PCB 真奇妙,进程管理不可少。
PID 来把号叫,状态优先全知晓。
程序计数寄存器,内存文件也记牢。
进程管理有高招,状态调度掌控好。
切换进程信息保,上下文里有法宝。
同步通信手段妙,信号队列不能抛。
资源管理也周到,基本单位很重要。
9,进程通信中的管道实现原理是什么?
pipe() 函数创建的管道处于一个进程中间,因此一个进程在由 pipe() 创建管道后,一般再使用 fork() 建立一个子进程,然后通过管道实现父子进程间的通信。管道两端可分别用描述字 fd[0] 以及 fd[1] 来描述。即一端只能用于读,由描述字 fd[0] 表示,称其为管道读端;另 一端则只能用于写,由描述字 fd[1] 来表示
具体步骤如下:
父进程调用 pipe 开辟管道,得到两个文件描述符指向管道的两端。
父进程调用 fork 创建子进程,那么子进程也有两个文件描述符指向同一管道。
父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里写,子进程可以从管道里读,管道是用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。
创建有名管道使用的是 mkfifo,再利用 open、read、write 读写数据
速记
Pipe 函数建管道,父子通信有高招。
Fork 子进程来报到,fd 描述分读写。
父写子读配合妙,环形队列数据跑。
Mkfifo 有名管道造,Open、读写数据到。
10,线程间的通信方式
线程间的通信是指多个线程之间为了协同工作、共享数据或传递信息而采用的交互方式。以下是常见的线程间通信方式的概念:
(1). 共享内存(Shared Memory)
- 概念:多个线程通过访问和修改同一块共享的内存区域(如全局变量、静态变量或堆内存)来实现通信。线程可以直接读写共享内存中的数据,从而实现信息的传递和同步。
- 特点:通信速度快,但需要额外的同步机制(如互斥锁、信号量)来避免数据竞争和不一致。
(2). 消息传递(Message Passing)
- 概念:线程之间通过发送和接收消息来通信。消息可以是简单的数据结构(如整数、字符串)或复杂对象。消息传递通常通过队列、管道或消息中间件实现。
- 特点:通信方式解耦,线程之间不需要直接访问共享内存,降低了数据竞争的风险,但通信开销可能较大。
(3). 信号量(Semaphore)
- 概念:信号量是一种用于控制线程对共享资源访问的同步机制。它通过计数器来限制同时访问资源的线程数量。线程在访问共享资源前需要获取信号量,访问完成后释放信号量。
- 特点:适用于资源竞争和线程同步的场景,但需要谨慎设计以避免死锁。
(4). 互斥锁(Mutex)
- 概念:互斥锁是一种用于保护共享资源的同步机制。线程在访问共享资源前需要获取锁,访问完成后释放锁。同一时间只有一个线程可以持有锁。
- 特点:简单直接,但可能导致线程阻塞,降低并发性能。
(5). 条件变量(Condition Variable)
- 概念:条件变量通常与互斥锁一起使用,用于线程间的条件同步。线程可以在满足特定条件时等待(阻塞),直到其他线程发出通知。
- 特点:适用于线程需要等待某个条件成立的场景(如生产者 - 消费者问题)。
(6). 事件(Event)
- 概念:事件是一种用于线程间通知的机制。线程可以设置或等待事件的发生。事件可以是手动重置或自动重置的。
- 特点:适用于简单的线程间通知场景,但功能相对单一。
(7). 屏障(Barrier)
- 概念:屏障是一种同步机制,用于让一组线程在某个点上等待,直到所有线程都到达该点后才能继续执行。
- 特点:适用于需要多个线程协同完成某个阶段任务的场景。
(8). 读写锁(Read - Write Lock)
- 概念:读写锁允许多个线程同时读取共享资源,但写入时只能有一个线程独占访问。适用于读多写少的场景。
- 特点:提高了并发性能,但需要合理设计读写操作。
(9). 管道(Pipe)
- 概念:管道是一种用于线程间或进程间通信的机制,通常通过文件描述符实现。线程可以通过管道发送和接收数据。
- 特点:适用于简单的数据流通信,但通常用于进程间通信,线程间通信较少使用。
(10). 信号(Signal)
- 概念:信号是一种用于线程间或进程间通知的机制。线程可以发送信号给其他线程,接收线程可以捕获信号并执行相应的处理函数。
- 特点:适用于简单的通知场景,但功能有限,且可能引发竞态条件。
速记
线程通信方式全,共享内存快当先。
直接读写数据传,同步机制不能欠。
消息传递解耦妙,队列管道中间跑。
数据结构随便挑,竞争风险能减少。
信号量来控资源,计数合理防死缠。
互斥锁儿保护严,同一时间一锁占。
条件变量协同干,特定条件再续缘。
事件通知挺简单,屏障多线共闯关。
读写锁分读和写,读多写少性能嗨。
管道通信虽存在,线程之间少依赖。
信号通知功能窄,竞态条件需细揣。
各种方式各有态,按需选用真不赖。
11,说说什么是信号量,有什么作用?
概念:信号量本质上是一个计数器,用于多进程对共享数据对象的读取,它主要是用来保护共享资源(信号量也属于临界资源),使得资源在一个时刻只有一个进程独享。
原理:由于信号量只能进行两种操作等待和发送信号,即 P(sv) 和 V(sv),具体的行为如下:
(1)P(sv) 操作:如果 sv 的值大于零,就给它减 1;如果它的值为零,就挂起该进程的执行(信号量的值为正,进程获得该资源的使用权,进程将信号量减 1,表示它使用了一个资源单位)。
(2)V(sv) 操作:如果有其他进程因等待 sv 而被挂起,就让它恢复运行,如果没有进程因等待 sv 而挂起,就给它加 1(若此时信号量的值为 0,则进程进入挂起状态,直到信号量的值大于 0,若进程被唤醒则返回至第一步)。
作用:用于多进程对共享数据对象的读取,它主要是用来保护共享资源(信号量也属于临界资源),使得资源在一个时刻只有一个进程独享。
速记
信号量呀像计数,多进程读共享处。
保护资源它来护,同一时刻独享有。
操作只有俩招数,P 和 V 要记住。
P 减一零就挂住,V 加一醒进程出。
共享资源稳守护,进程协调不添堵。
12,进程(作业)的调度算法
先到先服务(FCFS)调度算法 : 从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
短作业优先(SJF)的调度算法 : 从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。
时间片轮转调度算法 : 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称 RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。轮转法是基于适中的抢占策略的,以一个周期性间隔产生时钟中断,当中断发生后,当前正在运行的进程被置于就绪队列中,然后基于先来先去服务策略选择下一个就绪作业的运行。该算法即可用于作业调度,也可用于进程调度。
多级反馈队列调度算法 :前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程 。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
速记
进程调度有四招,听我来把诀窍道。
FCFS 先到先服务,队列先来先上路。
SJF 短作业优先,时间最短先往前。
RR 轮转时间片,公平分配把活干。
多级反馈队列妙,长短高低都顾到。
UNIX 用它都说好,调度算法真可靠。
13,进程同步的四种方法?
进程同步的四种方法包括:
临界区(Critical Section):对临界资源进行访问的代码叫做临界区,同时也是通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
互斥量(Mutex):为协调共同对一个共享资源的单独访问而设计。互斥量跟临界区很相似,比临界区复杂,互斥对象只有一个,只有拥有互斥对象的线程才具有访问资源的权限。通过互斥量可以指定资源被独占的方式使用,但如果有下面一种情况通过互斥量就无法处理,比如现在一位用户购买了一份三个并发访问许可的数据库系统,可以根据用户购买的访问许可数量来决定有多少个线程/进程能同时进行数据库操作,这时候如果利用互斥量就没有办法完成这个要求。
同步:多个进程因为合作产生的直接制约关系,使得进程有一定的先后执行关系。互斥:多个进程在同一时刻只有一个进程能进入临界区。
信号量(Semaphore):为控制一个具有有限数量用户资源而设计。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。
管程:使用信号量机制实现的生产者消费者问题需要客户端代码做很多控制,而管程把控制的代码独立出来,不仅不容易出错,也使得客户端代码调用更容易。
请注意,以上方法在不同的操作系统中可能略有不同,具体实现和使用应根据操作系统的特性和要求进行。
速记
进程同步有四招,听我慢慢来说道。
临界区里管访问,串行控制速度妙。
互斥量来很可靠,独占资源它承包。
许可数量若有调,互斥量就搞不了。
信号量儿也重要,资源访问有限条。
线程数目能限牢,共同访问乐逍遥。
管程一出真奇妙,控制代码独立好。
不易出错调用巧,生产消费没烦恼。
系统不同有高招,具体实现看需要。
进程与线程资源
14,进程切换为什么比线程更消耗资源?
进程和线程在操作系统中都是独立运行的实体,它们之间有许多相似之处,但也有一些重要的区别。进程是程序的动态表现,它可以独立地执行任务,拥有自己的内存空间和系统资源。而线程则是进程中的执行单元,多个线程共享同一个进程的资源(如内存空间、文件等)。
线程存在于进程中,一个进程可以有一个或多个线程。线程是运行在进程上下文中的逻辑流,这个线程可以独立完成一项任务。
进程切换比线程切换更消耗资源的原因主要有以下几点:
- 进程状态保存:进程切换时,需要将当前进程的所有状态信息(包括寄存器、内存、文件等)保存起来,以便下次再运行该进程时能够恢复到正确的状态。而线程切换时,只需保存线程的上下文信息,即一些寄存器和栈信息等,因此进程状态保存所需要的时间和空间成本相对较高。
- 页表切换:进程切换时需要刷新TLB(页表缓存/快表)并获取新的地址空间,以便能够正确地执行新的进程。而线程切换时则不需要进行页表切换,因为同一个进程内的线程共享同一个页表。页表切换的操作需要花费一定的时间和计算资源,因此增加了进程切换的开销。
- 资源分配和回收:进程切换时,需要重新为新进程分配系统资源(如内存、CPU时间等),同时将老进程的资源进行回收。而线程切换时,由于线程共享同一个进程的资源,不需要进行资源分配和回收,因此开销相对较小。
综上所述,进程切换比线程切换更消耗资源,主要是因为进程状态保存、页表切换和资源分配回收等操作需要花费更多的时间和计算资源。不过,在实际应用中,对于大型应用程序而言,由于其内部包含了多个线程,线程之间的通信和切换也会有一定的开销。
速记
进程线程两实体,相似区别要知悉。
进程动态有资源,线程寄身享共利。
进程切换成本高,状态页表资源耗。
线程切换开销少,上下文存就拉倒。
大型应用虽高效,线程通信也有扰。
15,进程之间私有和共享的资源
进程之间私有和共享的资源如下:
私有资源:
- 地址空间:每个进程都有其独立的地址空间,不允许其他进程直接访问。
- 堆:进程的堆是独立的,每个进程都有自己的堆,不允许其他进程直接访问。
- 全局变量:全局变量是进程内的共享变量,但是不同进程的全局变量是相互独立的,不允许其他进程直接访问。
- 栈:每个进程都有自己的栈,不允许其他进程直接访问。
- 寄存器:每个进程都有独立的寄存器组,不允许其他进程直接访问。
共享资源:
- 代码段:多个进程可以共享相同的代码段,这样可以节省内存空间。
- 公共数据:多个进程可以共享相同的公共数据,这样可以让不同进程之间进行数据交换。
- 进程目录:多个进程可以共享相同的进程目录,这样可以让不同进程之间进行进程管理。
- 进程ID:每个进程都有唯一的进程ID,这个进程ID是共享的,可以让不同进程之间进行进程识别和管理。
速记
进程资源分两种,私有共享要记清。
地址堆区和变量,栈与寄存器独享。
代码公共数据段,目录ID可共享。
节省内存易交换,管理识别更顺畅。
16,线程之间私有和共享的资源
线程之间私有和共享的资源如下:
私有资源:
- 栈:每个线程都有自己的栈,这是线程的私有空间,不允许其他线程直接访问。
- 寄存器:每个线程都有独立的寄存器组,不允许其他线程直接访问。
- 线程局部存储(TLS):TLS是一种变量的存储方法,该变量在它所在的线程内是全局可访问的,但是不能被其他线程访问到,这样就保持了数据的线程独立性。
共享资源:
- 全局变量:全局变量是所有线程都可以访问的资源,任何线程都有权利读取并执行任何代码。
- 堆上的数据:多个线程可以同时访问堆上的数据,这样可以提高程序的并行性和效率。
- 函数里的静态变量:静态变量是在函数内定义的,但是可以被多个函数或者多个线程同时访问。
- 程序代码:多个线程可以共享相同的程序代码,这样可以节省内存空间。
- 打开的文件:一个线程打开的文件可以由其他线程读写,这样可以让多个线程同时操作同一个文件。
速记
线程资源分两方,私有共享不一样。
栈与寄存TLS藏,私有空间莫乱闯。
全局堆数静变量,代码文件可共享。
并行高效内存省,协同操作真便当。
操作系统锁机制
17,介绍一下几种典型的锁?
在操作系统中,常见的锁类型有以下几种:
- 互斥锁(Mutex Lock):互斥锁是一种常见的线程同步机制,用于保护共享资源在多线程环境下的互斥访问。防止多个线程同时修改同一块内存空间。它提供了两个基本操作:加锁(Lock)和解锁(Unlock)。
- 读写锁(Read-Write Lock):读写锁允许多个线程同时读取共享资源,但在写操作时需要互斥访问。这种锁适用于读操作远多于写操作的情况。
- 自旋锁(Spin Lock):自旋锁是一种特殊的互斥锁,当一个线程尝试获取锁失败时,它会一直循环检查锁是否可用。优点是占用资源少,缺点是如果锁一直不可用,线程会一直占用 CPU 资源。
- 乐观锁(Optimistic Lock):乐观锁认为冲突不会经常发生,因此在执行操作时不会立即加锁,而是通过版本号等方式来检测是否出现冲突。常见的实现方式有 CAS 机制(Compare and Swap)。
- 递归锁(Recursive Lock):递归锁允许同一个线程多次获得同一个锁,适用于需要多次递归访问共享资源的情况。
以上是常见的几种操作系统中的锁类型,每种锁都有其特定的使用场景和优缺点,需要根据具体需求来选择合适的锁类型。
速记
系统锁类真不少,听我来把诀窍表。
互斥锁严护资源,加锁解锁保安全。
读写锁分读与写,读允同享写互斥。
自旋锁转不停歇,资源少占CPU劫。
乐观锁心很乐观,版本检测防冲突。
递归锁可重进入,递归场景它来护。
多进程与多线程
18,多进程与多线程间的对比、优劣与选择
多进程和多线程是操作系统中两种不同的并行计算模型。
多进程(Multi-Process) 是指操作系统能够同时管理多个进程并执行它们。每个进程都有自己的内存空间,且各自运行在自己的地址空间中。因此,多进程程序中的各个进程之间是相互独立的,它们之间需要通过进程间通信(IPC)机制来进行数据交换和同步。多进程编程需要考虑进程间的通信和同步问题,这些问题往往比较复杂,需要借助操作系统提供的各种 IPC 机制来解决。每一个进程是资源分配的基本单位。进程结构由以下几个部分组成∶代码段、堆栈段、数据段。代码段是静态的二进制代码,多个程序可以共享。实际上在父进程创建子进程之后,父、子进程除了 pid 外,几乎所有的部分几乎一样。父、子进程共享全部数据,但并不是说他们就是对同一块数据进行操作,子进程在读写数据时会通过写时复制机制将公共的数据重新拷贝一份,之后在拷贝出的数据上进行操作。如果子进程想要运行自己的代码段,还可以通过调用 execv() 函数重新加载新的代码段,之后就和父进程独立开了。
多线程(Multi-Thread) 是指一个进程内包含多个线程,这些线程共享进程的地址空间和资源。线程之间可以直接读写共享内存,因此多线程程序中的各个线程之间可以方便地共享数据。多线程编程需要考虑线程间的同步问题,例如防止多个线程同时修改同一份数据,防止死锁等问题。
多进程和多线程各有优劣:
多进程的优点:
- 稳定性高:一个进程崩溃不会影响其他进程。
- 安全性高:进程间的隔离性较强,不易发生数据泄露和恶意攻击。
- 可扩展性高:多核处理器可以并行执行多个进程。
- 易于管理:每个进程都有独立的地址空间和资源,方便管理和调试。
多进程的缺点:
- 进程间通信和同步开销较大。
- 创建和销毁进程的开销较大。
- 共享数据需要通过 IPC 机制,较为复杂。
多线程的优点:
- 线程间通信和同步开销较小,因为线程共享地址空间和资源。
- 创建和销毁线程的开销较小。
- 线程间可以直接读写共享内存,方便共享数据。
多线程的缺点:
- 一个线程崩溃可能导致整个进程崩溃。
- 线程间的竞争可能导致性能下降,例如多个线程同时访问同一份数据时可能导致资源争用和死锁等问题。
- 多线程的编程复杂度较高,需要考虑线程间的同步和互斥问题。
在选择多进程和多线程时,需要考虑以下因素:
- 应用程序的类型:如果是CPU 密集型应用程序,建议使用多线程;如果是IO 密集型应用程序,建议使用多进程。
- 应用程序的需求:如果需要高稳定性、高安全性和易于管理,建议使用多进程;如果需要高性能和方便共享数据,建议使用多线程。
速记
并行计算有两招,多进程来多线程。
进程独立各有家,内存隔离靠IPC。
代码堆栈数据段,写时复制变化大。
线程同处一进程,资源共享易沟通。
多进程强在稳定,安全扩展好管理。
通信开销却不小,创建销毁成本高。
多线程能省开销,数据共享真高效。
崩溃风险要注意,同步竞争得处理。
CPU密用线程,IO密用进程行。
稳定选进程,性能线程赢。
19,什么时候该用多线程,什么时候该用多进程?
例如,对于需要执行大量计算和数据处理的任务,多线程可以充分利用多核处理器的性能,提高程序的执行效率。而对于需要跨多个设备或平台进行分布式计算的任务,多进程可能更适合,因为可以在不同设备或平台上独立执行任务,并且每个进程可以独立管理自己的资源和数据。任务间相关性比较强的用多线程,相关性比较弱的用多进程。因为线程之间的数据共享和同步比较简单。可能要扩展到多机分布的用多进程,多核分布的用多线程。
速记
计算量大线程强,多核效能来帮忙;
分布计算进程棒,独立资源各自享。
任务相关线程上,同步共享不发慌;
多机就用进程扛,多核线程更擅长。
