• 进程和线程


    一、冯诺依曼体系结构

    现代的计算机, 大多遵守 冯诺依曼体系结构
    在这里插入图片描述

    • CPU中央处理器:进行算术运算和逻辑判断
    • 存储器: 分为内存和外村,用于存储数据
    • 输入设备: 用户给计算机发号施令的设备
    • 输出设备: 计算机给用户汇报结果的设备

    【补充】:

    1. CPU本质上由一大堆门电路构成
    2. CPU内部的集成程度越高,计算能力越强
    3. CPU上面还包含了寄存器,可以存储一些运算的中间结果
    4. 内存的存储空间小,访问速度快,价格高,断电后数据丢失
    5. 外存的存储空间大,访问速度慢,价格低,断电后数据不丢失
    6. 针对存储空间来说:硬盘>内存>>CPU
    7. 针对数据访问速度:CPU>>内存>硬盘
    8. CPU执行程序的过程:取指令、分析指令、执行指令

    二、操作系统

    由于CPU、存储器、输入设备、输出设备,都属于是硬件设备。普通用户和硬件设备进行交互是很困难的,操作系统就是用来解决这个问题的。

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

    1.1 定位

    在这里插入图片描述系统调用操作系统给应用程序提供的API接口
    例如:我们想在控制台打印一个“hello world”,首先调用printf这个库函数,这个库函数的内部就会调用操作系统提供的系统调用write,然后进入到内核来执行,内核进一步的控制硬件,完成输出.

    驱动程序:属于软件,由硬件厂商提供的,直接和硬件设备打交道,相当于在硬件和内核之间进行了一层转换.

    【补充】:
    当我们使用系统调用进入到操作系统内核的时候,会涉及到用户态到内核态之间的切换。由于内核只有一个,应用程序有很多,这些程序都需要靠这个内核来提供工作支持,此时很可能需要排队等待

    1.2 功能

    操作系统的核心功能:

    1. 对下,管理各种硬件设备;防止硬件被时空的应用程序滥用
    2. 对下,要给各种软件提供稳定的运行环境;向应用程序提供简单一致的机制来控制复杂而又通常大相径庭的低级硬件设备。

    操作系统是一个用来管理的软件,包括内存管理、文件管理、设备管理、进程管理等.

    三、进程

    3.1什么是进程

    每个应用程序运行于现代操作系统之上时,操作系统会提供一种抽象,好像系统上只有这个程序在运行,所有的硬件资源都被这个程序在使用。这种假象是通过抽象了一个进程的概念来完成的,进程可以说是计算机科学中最重要和最成功的概念之一。
    进程是操作系统对一个正在运行的程序的一种抽象,换言之,可以把进程看做程序的一次运行过程;同时,在操作系统内部,进程又是操作系统进行资源分配的基本单位。

    进程和程序的区别:
    例如:
    QQ进程,动态的,被加载到内存中的
    在这里插入图片描述
    QQ程序,属于可执行文件,静态的,存储在硬盘上的
    在这里插入图片描述
    一个计算机的硬盘上可能存储着很多的可执行文件,但同一时刻可能只有一小部分在运行

    二者主要区别:
    (1)程序是永存的;进程是暂时的,是程序在数据集上的一次执行,有创建有撤销,存在是暂时的;

    (2)程序是静态的观念,进程是动态的观念;

    (3)进程具有并发性,而程序没有;

    (4)进程是竞争计算机资源的基本单位,程序不是。

    (5)进程和程序不是一一对应的: 一个程序可对应多个进程即多个进程可执行同一程序; 一个进程可以执行一个或几个程序
    (6)进程是动态的,而程序是静态的。

    (7) 进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。

    (8)1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。

    3.2进程管理

    进程管理是操作系统内核的功能
    一个操作系统上同时运行着很多的进程,操作系统是如何将他们管理起来的呢?
    主要分为两个步骤:

    1. 先描述:通过类/对象将对进程的特征描述。计算机内部要管理任何现实事物,都需要将其抽象成一组有关联的、互为一体的数据。
    class PCB {
        // 进程的唯一标识 —— pid;
        // 进程关联的程序信息,例如哪个程序,加载到内存中的区域等
        //内存指针
        //文件描述符表
       // 分配给该资源使用的各个资源
        // 进度调度信息
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    形如上面的PCB,就代表着一个实实在在运行着的程序,也就是进程。
    【说明】:

    • pid :进程的唯一标识

    • 内存指针:操作系统需要程序中的一些必要的数据(需要运行的指令以及运行时依赖的数据)加载到内存中,内存指针用来描述该进程的内存中哪些部分是指令,哪些部分是数据

    • 文件描述符表: 用来表示当前的进程都打开了哪些文件

    • 内存指针和文件描述符表描述了当前进程持有的系统资源,认为进程是操作系统中“资源分配”的基本单位.

    • 进程里还有一些关键的属性,用来实现进程的调度,其中包括进程的优先级、进程的状态、进程的记账信息、进程的上下文


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

    3.3进程调度

    由于计算机的CPU是有限的,但进程的数量是比较多的,操作系统要做到尽可能地公平,就需要进行调度。

    3.3.1 并发式执行

    由于CPU的轮转速度是非常快的,CPU的主频达到1.9GHz,也就是1s内有19亿个时钟周期,人们从宏观上看,就好像是这些进程都在同时执行一样,但在微观上并不是同时执行的,而是轮流的占用CPU,我们也把这种执行方式叫做并发式执行

    3.3.2 并行式执行

    CPU上有多个核心,每个核心上都可以运行一个进程,同一时刻两个进程在两个CPU核心同时执行,这种执行方式叫做并行式执行。


    【二者的区别】:
    并发式执行:宏观上同时执行,微观上不是同时执行
    并行式执行:宏观上同时执行,微观上也是同时执行


    进程里有一些关键的属性,用来实现进程的调度,其中包括进程的优先级、进程的状态、进程的记账信息、进程的上下文

    对于这些属性的含义呢,我们先看下下面的这个例子,通过这个例子来理解一下。
    假如小绿是个漂亮的妹子,她的追求者有很多,她选男朋友的标准是:有钱,长的帅,会舔,但是没有同时具备这三个条件的人,小绿决定同时和A.B.C三个人交往,A很有钱,B长的帅,C很会舔.
    此时小绿需要化身成时间管理大师,周一和A逛街,周二和B吃饭,周三和C一起学习…
    如果此时将小绿看成CPU,把ABC看作是三个进程的话,在时间表的安排下,就好像是ABC三个进程并发的在CPU上执行

    进程优先级:每个进程都有相应的优先级,优先级决定它何时运行和接收多少 CPU 时间。
    在排时间表的时候,优先级就用来决定先给谁排,后给谁排。

    进程的状态: 进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。在五态模型中,进程分为新建态、终止态,运行态,就绪态,阻塞态。

    比如A说他要出差一周,那么就下来一周的时间,小绿给B和C安排就行了。“出差” 对于A来说就是一个特殊的状态,正常情况下,ABC的状态都是就绪状态,如果A出差了,A就进入了阻塞状态

    进程的记账信息: 操作系统在安排进程的时候,也会记录每个进程以往在CPU上执行的时间,如果发现某个进程被安排的太少,就会进行适当的调整。

    小绿在安排时间表的时候,会考虑到以往的时间安排,如果小绿发现前几周给C安排的时间都太少了,下一周就会给C安排更多的时间

    进程的上下文: 对于进程来说,具体指得是CPU里的一堆寄存器里面的值,上下文就会在进程被切出CPU的时候把寄存器的状态保存到PCB(内存),下次进程回到CPU上就把PCB里的上下文读取出来,恢复到CPU寄存器种

    也可以理解成进程在执行某个操作的时候,执行了一半就被调度走了,此时需要记录当前执行的操作执行到了哪里,方便调度回来的时候继续从当前位置继续向下执行

    3.4进程的虚拟地址空间

    在上面我们已经介绍了在进程的PCB中的内存指针,是用来描述当前进程持有哪部分内存空间的。
    在这里插入图片描述
    在这里插入图片描述
    同时由于虚拟地址空间的存在是进程具备隔离性。

    进程隔离性: 一个进程的运行不会影响到另一个进程,尤其是一个进程崩溃也不会影响到另一个进程

    【补充】:

    进程的隔离性,确实让系统更稳定了,但是也有别的问题但多个进程之间想要配合工作,就变得很麻烦 于是操作系统又引入了 “进程间通信”

    这里可能有些同学会有这样的疑问:如果每个进程都有一个"虚拟地址空间",一个系统里有很多的进程,那这些虚拟地址空间的总和超过了物理内存大了,该怎么办?
    主要有两个原因限制了这种情况的发生:

    1. 同一时刻执行的进程没有几个
    2. 即使同一时刻有很多进程在运行,这些进程也不是同时把所有的虚拟地址空间的内存都使用上了

    但也不妨存在极端情况,导致物理内存不足,出现这种bug的话,就需要程序员去进行优化或换一个内存更大的机器

    3.5进程间通信

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

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

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

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

    3.6父进程与子进程

    在多进程里,经常会谈到"父进程"与"子进程",例如,进程A中创建了进程B,那么A是B的父进程,B是A的子进程
    但是在多线程里,没有"父进程"与"子进程"的概念

    四、线程与多线程

    4.1线程的概念?

    一个线程就是一个 “执行流”. 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 “同时” 执行着多份代码.

    4.2 为什么会有线程?

    并发编程

    • 单核 CPU 的发展遇到了瓶颈. 要想提高算力, 就需要多核 CPU 而并发编程能更充分利用多核 CPU资源.
    • 有些任务场景需要 “等待 IO”, 为了让等待 IO 的时间能够去做一些其他的工作, 也需要用到并发编程

    虽然多线程也能实现并发编程,但是线程比进程更轻量

    • 创建、销毁线程都比创建、销毁进程更快
    • 调度线程比调度进程更快

    【补充】:
    创建进程的步骤:

    1. 创建PCB
    2. 分配系统资源(主要是内存空间,比较消耗时间)
    3. 将PCB挂到就绪队列中

    同一个进程里的若干线程之间的关联关系:

    1. PCB中的"线程组id"相同
    2. PCB里的内存指针和文件描述符表是同一份

    由于创建、销毁进程很消耗时间,为了提高效率,便引入了"线程",线程也可叫做"轻量级进程"

    线程是包含在进程中的,(一个进程里可以有多个线程),每个线程也都有自己的PCB,同一个进程里的多个线程之间,共用同一份系统资源,这意味着新创建的线程无需重新分配系统资源,只需和它出于同一进程里其他线程共用一份系统资源,这就是创建线程比创建进程更省时的原因。

    下面这个例子进一步帮助大家理解多进程和多线程
    在这里插入图片描述
    但并不是线程数越多越好,因为随着线程数的增加,CPU的核心逐渐被吃满后,再继续增加线程数,已经没有意义了,也就是说,使用多线程确实能够提高效率,但前提是多喝资源是充分的,随着线程的增加,CPU的核心数都被吃满了,此时在继续增加线程,就已经没有意义了,这是速度不会提升,反而额外增加调度的开销

    但是这里还会涉及到一个问题就是,多个线程之间不会相互影响吗,也就是说多个滑稽老铁之间不会相互打架吗?会,如果两个滑稽老铁相中了同一个鸡腿,那么此时就可能发生冲突。
    在多线程的角度上,可以理解成多个线程访问同一个变量的时候,也有可能发生冲突,这属于我们后面要学的线程安全问题

    还有一个更严重的问题就是,如果某个滑稽因为没有抢过别人,直接把桌子掀了,那么其他人也都吃不到了
    这就相当于,在一个进程中的某个线程抛出异常(如果catch了这个异常就安全了),如果没有得到妥善的处理,就可能导致整个进程都崩溃。

    4.3 进程和线程的区别

    • 进程是包含线程的,每个进程至少有一个线程存在,即主线程
    • 每个进程都有独立的虚拟地址空间和文件描述符表等资源,而同一个进程的多个线程之间则共用这一份虚拟地址空间和文件描述符表等资源(即进程中的线程之间共享进程的所有资源)
    • 进程是系统分配资源的最小单位,线程是CPU调度的最小单位
    • 多个进程同时执行的时候,如果一个进程挂了,一般不会影响其他的进程;同一个进程内的多个线程之间,如果一个线程挂了,同进程中的其他线程很可能也受到影响
    • 线程的创建、销毁、调度效率比进程更高,并且有自己独立的执行任务。

    4.4 Java线程和操作系统线程的关系

    线程是操作系统中的概念,操作系统内核实现了线程这样的机制,并且对用户层提供了一些API供用户使用。(Linux中的pthread库)
    Java标准库的中的Thread类可以视为是对操作系统提供的API进行了进一步的抽象和封装

  • 相关阅读:
    C++闲谈03——多线程
    Linux权限
    非零基础自学Java (老师:韩顺平) 第8章 面向对象编程(中级部分) 8.4 包
    【Linux网络】Linux网络设置
    Nginx重写功能
    Spring Cloud Function SpEL 漏洞复现
    Leetcode 440. 字典序的第K小数字
    小程序的多种特性
    stable diffusion实践操作-webUI教程-不是基础-是特例妙用
    git初识
  • 原文地址:https://blog.csdn.net/m0_60631323/article/details/125929461