ThankNeko's Blog ThankNeko's Blog
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)

Hoshinozora

尽人事,听天命。
首页
  • 操作系统

    • Linux基础
    • Linux服务
    • WindowsServer笔记
    • Ansible笔记
    • Shell笔记
  • 容器服务

    • Docker笔记
    • Kubernetes笔记
    • Git笔记
  • 数据库服务

    • MySQL笔记
    • ELK笔记
    • Redis笔记
  • 监控服务

    • Zabbix笔记
  • Web服务

    • Nginx笔记
    • Tomcat笔记
  • 数据处理

    • Kettle笔记
  • Python笔记
  • Bootstrap笔记
  • C笔记
  • C++笔记
  • Arduino笔记
  • 分类
  • 标签
  • 归档
  • 随笔
  • 关于
GitHub (opens new window)
  • Python笔记

    • 基础知识

    • 并发编程

      • 并发相关介绍
        • 并发与并行介绍
        • 多道技术
        • 进程调度
        • 进程运行的三状态
        • 两对重要概念
      • 多进程与进程间通信
      • 多线程与线程间通信
      • 其他锁与队列
      • 网络IO模型与协程
    • 爬虫笔记

    • 模块笔记

    • 后端笔记

  • C笔记

  • C++笔记

  • Arduino笔记

  • Web笔记

  • Dev
  • Python笔记
  • 并发编程
Hoshinozora
2023-02-25
目录

并发相关介绍

# 并发与并行介绍

image-20251025113744494

# 并发

看起来像同时运行的,就是并发。

# 并行

真正的同时执行,就是并行。

# 注意

并行可以称之为并发,但并发不能称之为并行。

单核计算机无法实现并行,但可以实现并发。

# 多道技术

# 作用

让单核也能实现并发的效果,节省多个程序运行时的总耗时。

# 单道与多道的区别

单道(串行):等前面的任务执行完,才会执行后面的任务。

任务A(读取到内存,CPU处理)
↓
任务B(读取到内存,CPU处理)
↓
任务C(读取到内存,CPU处理)
1
2
3
4
5

多道(并行):在CPU处理任务A的时候,控制硬盘提前将任务B读入,然后在CPU处理完任务A后,就可以立马处理任务B,同时控制硬盘读取任务C到内存,后续以此类推。

任务A-读到内存 —> 任务A-CPU处理 —> 任务C-读到内存 —> 任务C-CPU处理... ...
                 任务B-读到内存 —> 任务B-CPU处理 —> 任务D-读到内存... ...
1
2

# 多道技术重点

空间上的复用:多个程序共用一套计算机硬件。

时间上的复用:通过切换和保存状态,提高程序的运行效率。多道技术的耗时,一般以耗时最久的任务为准。

# 切换

切换是为了节省耗时,在某硬件处理完某个任务的某部分后,立即切换来处理其他的任务。

触发CPU切换的两种情况:

情况一:

当一个程序遇到IO操作的时候,操作系统会剥夺该程序的CPU执行权限。

由于程序IO操作时CPU是不工作的,所以在这种情况下,操作系统会将CPU的执行权限分配给其他需要CPU的程序,而在程序IO操作完后,又会将CPU的执行权限重新分配回去。

作用是提高CPU的利用率,并且不影响程序的执行效率。

情况二:

当一个程序长时间占用CPU的时候,操作系统会剥夺该程序的CPU执行权限,然后与其他程序轮询着共用,会给人一种并发的错觉。

作用是虽然降低了程序的执行效率 (原本时间+切换时间),但切换时间是非常快的,人难以感知,会给人多个程序同时执行的感觉。

# 保存状态

保存状态是为了再切换回去时,能够继续上一个任务的运行。

# 进程调度

# 先来先服务调度算法

对长作业有利,对短作业有弊。因为长作业工作时,短作业只能一直等待,直到长作业工作完,现在已经被淘汰。

# 短作业优先调度算法

对短作业有利,对长作业无益。在遇到短作业时,将长作业放到后面再工作,优先处理短作业。

# 时间片轮转法 + 多级反馈队列

在进程运行时,会给每个程序分配1个时间片。

时间片就是一段固定的时间(比如3微秒、3毫秒等),CPU会根据进程的时间片数量,来决定优先级。

如果进程运行了1个时间片还没有结束,就会再给该进程分配1个时间片。分配的时间片次数越多,说明程序运行的时间越长,任务执行的优先级也就会越低。

不同的分配次数代表着不同的队列,比如分配1个时间片的就是第一队列,分配2个时间片就是第二队列,以此类推。

同一队列里的进程会依次运行。只有当高优先级队列均空时,才会调度后面低优先级队列中的进程运行。

如果高优先级队列出现了新的任务,CPU就会暂停正在执行的低优先级队列的任务,以运行前面高优先级队列的任务。

我们还可以通过工具手动给任务设置优先级,但一般情况不用特意的设置优先级。

# 进程运行的三状态

# 介绍

在程序运行后,程序会进入以下几个状态。

进程的阻塞结束后,并不会立刻运行接下来的代码,而是先就绪,等待操作系统调度,然后再运行。

# 就绪状态

当进程已已具备运行的条件,但是还没有被分配到CPU,这时的进程状态称为就绪状态。

例如:从硬盘读取代码到内存等。

# 运行状态

当进程已分配到CPU,其程序正在CPU中执行,此时的进程状态称为执行状态。

例如:print("running...")

# 阻塞状态

正在执行的进程,由于某个事件需要进行等待,便会放弃CPU进入阻塞状态。

引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。

例如:sleep(3)、input()、accept()等。

# 两对重要概念

# 同步和异步

同步和异步针对的是函数/任务的调用方式。

同步

任务提交之后,一直等待任务的结果返回,才会继续执行下一步,等待的过程中不做任何事。

import time
def func():
    time.sleep(3)
    print(aaa)
res = func()
print(bbb)
1
2
3
4
5
6

异步

任务提交之后,不原地等待任务的结果返回,而是去做其他的事情。

等到任务完成后,会有一个异步回调机制(回调函数)来对其任务结果进行处理。

# 阻塞和非阻塞

阻塞和非阻塞针对的是进程或线程的运行状态。

阻塞:阻塞状态。

非阻塞:就绪状态和运行状态。

我们应该尽量让我们写的代码运行时,只在就绪态和运行态之间切换。

# 上述概念的组合

最高效的一种组合:异步非阻塞,异步非阻塞的框架非常的快。

#并发与并行#多道技术#进程调度#进程三状态#同步与异步#阻塞与非阻塞
反射与元类
多进程与进程间通信

← 反射与元类 多进程与进程间通信→

最近更新
01
Vue路由
12-09
02
FastAPI实现用户管理
11-23
03
Tortoise ORM
11-23
更多文章>
Theme by Vdoing | Copyright © 2022-2026 Hoshinozora | MIT License
湘ICP备2022022820号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式