操作系统、进程和线程

简介: 操作系统、进程和线程

一、操作系统

操作系统是一组做计算机资源管理的软件的统称。目前常见的操作系统有:Windows系列、Unix系列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等。

操作系统的定位如下:

操作系统由两个基本功能:

1) 防止硬件被应用程序滥用

2) 向应用程序提供简单一致的机制来控制复杂而又通常大相径庭的低级硬件设备。

二、进程/任务(Process/Task)

1. 什么是进程/任务

每个应用程序运行于现代操作系统之上时,操作系统会提供一种抽象,好像系统上只有这个程序在运行,所有的硬件资源都被这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之一。

人话:每个应用程序在内存运行时就是一个进程

2. 进程控制块抽象(PCB Process control Block)

计算机内部要管理任何现实事物,都需要将其抽象成一组有关联的、互为一体的数据。在 Java 语言中,我们可以通过类/对象来描述这一特征。

// 以下代码是 Java 代码的伪码形式,重在说明,无法直接运行
class PCB {
// 进程的唯一标识 —— pid;
// 进程关联的程序信息,例如哪个程序,加载到内存中的区域等
// 分配给该资源使用的各个资源
// 进度调度信息(留待下面讲解)
}

我们这里用类去类比PCB,但是操作系统都是用C语言写的,所以应该把PCB描述成一个结构体更加合适

一个PCB一般包含如下信息:

(1)pid:每个进程需要有一个唯一的身份标识~

(2)内存指针:当前这个进程使用的内存是哪一部分

(3)文件描述符表:进程运行的时候,使用了哪些硬盘上的资源

这样,每一个 PCB 对象,就代表着一个实实在在运行着的程序,也就是进程。

操作系统再通过这种数据结构,例如线性表、搜索树等将 PCB 对象组织起来,方便管理时进行增删查改的操作。

3. CPU分配 —— 进程调度(Process Scheduling)

注:进程是计算机分配资源的基本单位!!!(死记)

为了便于讨论和理解,我们大部分的场景下假设是单CPU单核的计算机。

操作系统对CPU资源的分配,采用的是时间模式 —— 不同的进程在不同的时间段(时间片)去使用 CPU 资源。

首先了解什么是并行和并发:

并行:同一时刻,两个核心,同时执行两个进程,此时这两个进程就是并行执行~

并发:一个核心,先执行进程1,执行一会之后,再去执行进程2,在执行一会之后,再去执行进程3,此时只要这里的切换速度足够快,看起来,进程123就是“同时”执行

例如:一个CPU有16个核心,也可以同时执行142个任务!通过并发+并行的方式来完成,这种状态完全是有操作系统只是控制的,程序猿根本感知不到~~,所以很多时候就把并行+并发统称为并发!【并发程度更高了,就可以称为高并发。比如一个核心(主体)并发指向了1w个任务!!,就可以称为“高并发”】

接下来这一组属性,都是描述CPU资源相关的属性。这些属性都是辅助进程调度:

a) 进程状态

简单认为,进程状态主要是这两个:

就绪态:该进程已经准备好了,随时可以上CPU执行

阻塞态:该进程暂时无法上CPU执行

举个栗子:

我同时交三个男朋友,每周要给这三个小哥哥(A、B、C)安排时间表~

默认情况下,这三个小哥哥都是随叫随到,我在排时间就十分灵活,也就是每个人都是就绪态。

假设A和我说,他要出差一个月~~

于是A就相当于阻塞态,B和C就是就绪态

b) 进程的优先级

进程之间的调度不一定是“公平”的,有优先级之分

举个栗子:

A最有钱,B最帅,C最会舔

那么在我眼中,A的优先级最高,可能每周会排4天给A,然后是B,最后才是C。

c) 进程的上下文

上下文,就是描述当前进程执行到哪里(也就是存档记录),为什么会有这个存单记录呢,因为CPU在调度每个进程都是随机的,由时间片决定。

进程在离开CPU的时候就要把当前运行的中间结果“存档”,等下次进程再次被CPU调度的时候,再回复之前的“存档”,从上次的结果继续往后指向~~【如果进程结束了,就不必村了,如果是暂时离开,就得存!】

举个栗子:

有一天,我和A在一起,A给我说:“下个月,我带你去南澳岛玩玩,你准备准备。”此时,我就可以准备一套性感的内衣。

第二天,我和B在一起,B给我说:“下个月,他的妈妈要过生日,他想让我帮忙挑选个礼物,也让我准备准备。”我准备给他妈妈挑选个手机。

过了一段时间之后,此时,A问我准备得咋样,我说手机买好了。B问我准备得咋样,我说内衣买好了,这就尴尬了~~

为了避免这种情况,我就需要在时间安排表上记录一下:和他们做了什么时,保证下次和他们在一次不会出差错!

具体到进程,所谓的上下文具体指就是进程的运行过程中,CPU内部的一系列寄存器的值

d) 进程的记账信息

统计了每个进程,在CPU上执行了多久了,可以作为调度的参考依据,可能会给一个执行时间少的进程增加他的调度次数

比如,按照之前的优先级,每周只给C排一天的实践~~

过了几个月之后,我就发现C对我的态度逐渐冷淡了,舔得力不从心

此时排查之前的时间表,原来排给C的时间太少了,难怪感情就淡了~

接下来的实践里给C多排点时间,多给他点甜头。

4. 内存分配 —— 内存管理(Memory Manage)

操作系统对内存资源的分配,采用的是空间模式 —— 不同进程使用内存中的不同区域,互相之间不会干扰.

操作系统给进程分配的内存,是以“虚拟地址空间”的方式进行分配的,每个进程范围的内存地址,都不是真实的物理地址。

人话:页表其实就相当于一个检测员,看看你的给的地址是否正确。保证了一个进程的独立性,一个进程无法直接干预另一个进程的内存内容,每个进程都有自己的独立的地址空间。大大提升了操作系统的“稳定性”。

5. 进程间通信(Inter Process Communication)

如上所述,进程是操作系统进行资源分配的最小单位,这意味着各个进程互相之间是无法感受到对方存在的,这就是操作系统抽象出进程这一概念的初衷,这样便带来了进程之间互相具备“隔离性
(Isolation)”

但现代的应用,要完成一个复杂的业务需求,往往无法通过一个进程独立完成,总是需要进程和进程进行配合地达到应用的目的,如此,进程之间就需要有进行“信息交换“的需求。进程间通信的需求就应运而生。

目前,主流操作系统提供的进程通信机制有如:管道、共享内存、文件、网络、信号量、信号

其中,网络是一种相对特殊的 IPC 机制,它除了支持同主机两个进程间通信,还支持同一网络内部非同一主机上的进程间进行通信。

举个栗子:

一个小区因为疫情封了,外面的人进不来,里面的人出不去。

我想点外卖,外卖员就会把外卖送到保安亭(相当于公共空间

外卖员是一个进程,我是一个进程!

三、线程(Thread)

前面讲了那么多进程的知识,目的不在讲进程,而是为了引出线程!!!

1. 什么是线程

首先,我们得知道进程,是比较“重量的”,速度慢,消耗资源多的

创建一个进程,成本比较高

销毁一个进程,成本也比较高

调度一个进程,成本也挺高的……

所以多进程编程,可以解决并发的问题,但不是一个高效的选择!

为什么进程这么有“重量”?

主要体现在资源分配上,资源分配是一个耗时的操作(包括了内存分配,文件读取分配等等)

引入线程:

举个栗子:

我的大姨想要扩建自己的厂子,有两种方案

(1)再去找个地皮,重新建立物流系统等等(多进程)

(2)在原本的厂子上进行扩建,不需要重新建立物流系统,做到了资源共享,同时提高了出货量(多线程)

我们再次回顾下进程调度:

(1)为啥要调度?狼多肉少(进程多,CPU处理不过来)

(2)CPU按照并发的方式来执行进程的

(3)PCB中提供了一些属性,进程的优先级、进程的状态、进程的上下文、进程的记账信息……

2. 线程和进程的关系

进程包含线程,一个进程里可以有一个线程,或者多个线程。每个线程都是一个独立的执行流。多个线程直接,也是并发执行的。

一个进程中的多个线程之间,共用同一份系统资源,包含了①内存空间、②文件描述符表

只有在进程启动,创建第一个线程的时候,需要花成败去申请系统资源,一旦进程(第一个线程)创建完毕,此时,后续再创建的线程,就不必再申请资源了,创建/销毁的效率也提高了不少。(线程也被称为“轻量级”的进程)

总结进程和线程的区别:

  1. 进程包含线程。
  2. 进程有自己独立的内存空间和文件描述符表。同一个进程中的多个线程之间共享同一份地址空间和文件描述符表。
  3. 进程是操作系统资源分配的基本单位,线程是操作系统调度执行的基本单位
  4. 进程之间具有独立性,一个进程挂了,不会影响到别的进程;同一个进程里的多个线程之间,一个线程挂了,可能会把整个进程带走,影响到其他线程的。

四、问题提问和解答

(1)计算机在什么情况下会再创建一个进程

答:取决于你的代码咋写。创建进程和创建线程都是程序猿可以控制的~~。例如同一个程序,内部想要并发地完成多组任务,此时使用多线程比较合适(比如:微信,是一个程序,里面同时聊天、看朋友圈等等可以理解为线程)。多个程序之间,此时就是多个进程了(比如:微信、QQ音乐等等)。

(2)进程里的多线程有没有上限呢?

答:只要系统资源够,没有上限的。但也不是线程越多越好。

五、各个技术面试的多频考点

(1)谈到JavaSE,最高频的问题是多态

(2)谈到数据结构,最高频的问题是哈希表的实现

(3)谈到数据库,最高频的问题是索引和事务

(4)谈到系统编程,最高频的问题是进程和线程的基本概念和区别

相关文章
|
12天前
|
机器学习/深度学习 算法 调度
深入理解操作系统之进程调度策略
【4月更文挑战第30天】 在多任务操作系统中,进程调度策略是核心组成部分之一,其决定了处理器资源分配的合理性与效率。本文将详细探讨现代操作系统中常见的进程调度算法,包括它们的原理、特点以及适用场景。通过对比分析先来先服务(FCFS)、短作业优先(SJF)以及轮转调度(RR),我们旨在提供一个全面的视角以帮助读者深刻理解不同调度策略对操作系统性能的影响。此外,文章还将讨论如何根据实际需求选择和优化调度算法,以及未来可能的发展趋势。
|
20小时前
|
Unix Linux 调度
linux线程与进程的区别及线程的优势
linux线程与进程的区别及线程的优势
|
2天前
|
算法 Linux 调度
深入理解操作系统:进程管理与调度策略
【5月更文挑战第10天】 本文将深入探讨操作系统的核心机制之一:进程管理。我们将从进程的概念入手,解析其生命周期,进而展开对操作系统中进程调度策略的详细讨论。文中不仅涉及理论分析,还结合了现代操作系统如Linux的实际案例,以期提供一个全面而深刻的视角。通过阅读本文,读者将对操作系统如何高效地管理计算资源有更深层次的理解。
|
3天前
|
Java 调度
【Java多线程】对进程与线程的理解
【Java多线程】对进程与线程的理解
11 1
|
5天前
|
算法 调度 UED
深入理解操作系统的进程调度策略
【5月更文挑战第7天】 在现代计算机系统中,操作系统的核心职责之一是确保CPU资源的有效分配与利用。本文旨在探讨操作系统中的进程调度策略,并分析其对系统性能的影响。我们将从调度的基本概念出发,介绍几种常见的调度算法,如先来先服务、短作业优先和轮转调度等,并对它们的优缺点进行比较。此外,文章还将讨论多级反馈队列调度策略,它结合了多种调度方法的优点,以适应不同类型的工作负载。通过深入分析,本文旨在为读者提供一个清晰的框架,以理解操作系统如何管理并发执行的多个进程,以及这些管理策略如何影响系统的整体效率和响应性。
|
6天前
|
算法 调度
深入理解操作系统:进程管理与调度策略
【5月更文挑战第5天】 在现代计算机系统中,操作系统的核心职能之一是高效地管理计算机资源,尤其是处理多个并发运行的程序(进程)。本文将探讨操作系统中的进程管理机制,重点分析不同的进程调度策略及其对系统性能的影响。我们将从理论和实践的角度出发,比较各种调度算法的优劣,并提出在特定场景下如何选择最合适的调度策略。通过深入剖析进程调度的原理和实现细节,旨在为读者提供全面而深刻的认知框架,以便于更好地理解和优化操作系统的性能。
|
8天前
|
算法 调度 云计算
深入理解操作系统:进程管理与调度策略
【5月更文挑战第4天】本文将深入探讨操作系统中的关键组成部分——进程管理,以及如何通过有效的进程调度策略提升系统性能。我们将剖析进程的概念、状态转换和控制,并详细分析不同的进程调度算法,如先来先服务(FCFS)、短作业优先(SJF)和多级反馈队列(MLFQ)。文章旨在为读者提供一个清晰的框架,以理解操作系统如何处理并发任务,保证系统资源的有效利用和响应性。
|
10天前
|
负载均衡 算法 调度
深入理解操作系统:进程管理与调度策略
【5月更文挑战第2天】 在现代计算环境中,操作系统的核心职能之一是确保系统资源的高效利用和任务的顺畅执行。本文将探讨操作系统中的关键组件——进程管理及其调度策略。通过对进程的概念、生命周期以及调度算法的详细分析,我们旨在揭示操作系统如何协调多个运行中的程序,以实现快速响应和资源优化。文章还将讨论不同类型操作系统(如实时操作系统和通用操作系统)中进程调度策略的差异性及其对系统性能的影响。通过理论与实践相结合的方式,本文为读者提供了一个全面了解操作系统进程管理的平台。
|
10天前
|
负载均衡 算法 大数据
深入理解操作系统:进程管理和调度策略
【5月更文挑战第1天】 在现代操作系统的核心功能中,进程管理与调度策略是确保系统高效、稳定运行的关键。本文旨在深入剖析操作系统中的进程概念、进程状态转换以及进程调度机制。通过对先进先出、最短作业优先和时间片轮转等调度算法的比较分析,我们不仅揭示了它们在资源分配和任务执行中的应用,还讨论了它们在不同场景下的表现和局限性。此外,文章还将探讨多核处理器环境下的调度策略演变,以及未来操作系统在进程管理方面可能面临的挑战。
|
11天前
|
算法 调度
深入理解操作系统中的进程调度策略
【5月更文挑战第1天】在多任务操作系统中,进程调度策略是决定系统性能和响应能力的关键因素。本文将详细探讨现代操作系统中常见的进程调度算法——从简单的先来先服务(FCFS)到复杂的多级反馈队列(MLFQ),以及实时系统中的立即模式和时间片轮转(RR)。我们将分析每种调度策略的工作原理、优势、局限性以及它们如何影响操作系统的整体表现。通过比较不同策略在各种负载场景下的表现,读者将能更好地理解如何为特定应用选择最合适的调度策略。