操作系统、进程和线程

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

一、操作系统

操作系统是一组做计算机资源管理的软件的统称。目前常见的操作系统有: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)谈到系统编程,最高频的问题是进程和线程的基本概念和区别

相关文章
|
23天前
|
算法 调度 UED
深入理解操作系统:进程调度与优先级队列
【10月更文挑战第31天】在计算机科学的广阔天地中,操作系统扮演着枢纽的角色,它不仅管理着硬件资源,还为应用程序提供了运行的环境。本文将深入浅出地探讨操作系统的核心概念之一——进程调度,以及如何通过优先级队列来优化资源分配。我们将从基础理论出发,逐步过渡到实际应用,最终以代码示例巩固知识点,旨在为读者揭开操作系统高效管理的神秘面纱。
|
2天前
|
调度 开发者
深入理解:进程与线程的本质差异
在操作系统和计算机编程领域,进程和线程是两个核心概念。它们在程序执行和资源管理中扮演着至关重要的角色。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
15 5
|
18天前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
17天前
|
消息中间件 安全 算法
深入理解操作系统:进程管理的艺术
【10月更文挑战第38天】在数字世界的心脏,操作系统扮演着至关重要的角色。它不仅是硬件与软件的桥梁,更是维持计算机运行秩序的守夜人。本文将带你走进操作系统的核心——进程管理,探索它是如何协调和优化资源的使用,确保系统的稳定与高效。我们将从进程的基本概念出发,逐步深入到进程调度、同步与通信,最后探讨进程安全的重要性。通过这篇文章,你将获得对操作系统进程管理的全新认识,为你的计算机科学之旅增添一份深刻的理解。
|
21天前
|
算法 调度 UED
深入理解操作系统:进程管理与调度策略
【10月更文挑战第34天】本文旨在探讨操作系统中至关重要的一环——进程管理及其调度策略。我们将从基础概念入手,逐步揭示进程的生命周期、状态转换以及调度算法的核心原理。文章将通过浅显易懂的语言和具体实例,引导读者理解操作系统如何高效地管理和调度进程,保证系统资源的合理分配和利用。无论你是初学者还是有一定经验的开发者,这篇文章都能为你提供新的视角和深入的理解。
40 3
|
22天前
|
Linux 调度 C语言
深入理解操作系统:进程和线程的管理
【10月更文挑战第32天】本文旨在通过浅显易懂的语言和实际代码示例,带领读者探索操作系统中进程与线程的奥秘。我们将从基础知识出发,逐步深入到它们在操作系统中的实现和管理机制,最终通过实践加深对这一核心概念的理解。无论你是编程新手还是希望复习相关知识的资深开发者,这篇文章都将为你提供有价值的见解。
|
19天前
|
Java
java小知识—进程和线程
进程 进程是程序的一次执行过程,是系统运行的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。 线程 线程,与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间做切换工作时,负担要比
25 1
|
24天前
|
算法 调度 UED
深入理解操作系统的进程调度机制
本文旨在探讨操作系统中至关重要的组成部分之一——进程调度机制。通过详细解析进程调度的概念、目的、类型以及实现方式,本文为读者提供了一个全面了解操作系统如何高效管理进程资源的视角。此外,文章还简要介绍了几种常见的进程调度算法,并分析了它们的优缺点,旨在帮助读者更好地理解操作系统内部的复杂性及其对系统性能的影响。
|
25天前
深入理解操作系统:进程与线程的管理
【10月更文挑战第30天】操作系统是计算机系统的核心,它负责管理计算机硬件资源,为应用程序提供基础服务。本文将深入探讨操作系统中进程和线程的概念、区别以及它们在资源管理中的作用。通过本文的学习,读者将能够更好地理解操作系统的工作原理,并掌握进程和线程的管理技巧。
37 2
|
25天前
|
消息中间件 算法 Linux
深入理解操作系统之进程管理
【10月更文挑战第30天】在数字时代的浪潮中,操作系统作为计算机系统的核心,扮演着至关重要的角色。本文将深入浅出地探讨操作系统中的进程管理机制,从进程的概念入手,逐步解析进程的创建、调度、同步与通信等关键过程,并通过实际代码示例,揭示这些理论在Linux系统中的应用。文章旨在为读者提供一扇窥探操作系统深层工作机制的窗口,同时激发对计算科学深层次理解的兴趣和思考。