32. 线程、进程与协程

一、什么是多任务

  如果一个操作系统上同时运行了多个程序,那么称这个操作系统就是 多任务的操作系统,例如:Windows、Mac、Android、IOS、Harmony 等。如果是一个程序,它可以同时执行多个事情,那么就称为 多任务的程序

  一个 CPU 默认可以执行一个程序,如果想要多个程序一起执行,理论上就需要多个 CPU 来执行。

  如果一个 CPU 是一个核心,理论上只能同时运行一个任务,但是事实上却可以运行很多个任务。这是因为操作系统控制着 CPU,让 CPU 做了一个特殊的事情,一会运行一个任务,然后快速的运行另一个任务,依次类推,实现了多个任务,看上去 “同时” 运行多个任务。

并发:是一个对假的多任务的描述;

并行:是真的多任务的描述;

二、进程与线程

  计算机程序只是存储在磁盘上的可执行二进制(或其它类型)文件。只有把它们加载到内存中从被操作系统调用,才拥有其生命期。

  进程(process)则是一个执行中的程序。每个进程都拥有自己的地址空间、内存、数据栈以及其它用于跟踪执行的辅助数据。操作系统管理其上所有进程的执行,并为这些进程合理分配时间。进程也可以通过派生新的进程来执行其它任务,不过因为每个新进程也都拥有自己的内存和数据栈等,所以只能采用进程间通信的方式共享数据;

  线程(thread)与进程类似,不过它们是同一个进程下执行的,并共享相同的下上文。线程包括开始、执行顺序和结束三部分。它有一个指令指针,用于记录当前运行的上下文。当其它线程运行时,它可以被抢占(中断)和临时挂起(也称为睡眠)—— 这种做法叫做让步(yielding)。

  一个进程中的各个线程与主线程共享同一片数据空间。线程一般是以并发方式执行的。在单核 CPU 系统中,因为真正的并发是不可能的,所以线程的执行实际上是这样规划的:每个线程运行一小会,然后让步给其它线程(再次排队等待更多的 CPU 时间)。在整个进程的执行过程中,每个线程执行它自己特定的任务,在必要时和其它线程进行结果通信。

  但是这种共享数据也是存在风险的。如果两个或多个线程访问同一片数据,由于数据访问顺序不同,可能导致结果不一致。这种情况通常称为 “竞态条件”(race condition)。另一个需要注意的问题时,线程无法给予公平的执行时间。这是因为一些函数会在完成前保持阻塞状态,如果没有专门为多线程情况进行修改,会导致 CPU 的时间分配向这些贪婪的函数倾斜。

  在实现多任务时,线程切换从系统层面远不止保存和恢复 CPU 上下文这么简单。操作系统为了程序运行的高效性,每个线程都有自己缓存 Cache 等数据。操作系统还会帮你做这些数据的恢复操作。所以线程的切换比较耗性能。但是协程的切换只是单纯的操作 CPU 的上下文。

线程是计算机中可以被 CPU 调度的最小单元,进程是计算机资源分配的最小单元;进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域;

一个程序,至少有一个进程,一个进程中至少有一个线程,最终是线程在工作;

一个进程内可以开设多个线程,在用一个进程内开设多个线程无需再次申请空间及拷贝代码的操作,开设线程的开销远远的要小于进程的开销;

单核 CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务。但是因为 CPU 时间单元特别短,因此感觉不出来;

三、多进程的使用场景

  多进程 适合 计算密集型 的场景。

【1】、多进程的使用

import os, timefrom multiprocessing import Processdef task():val = 1for i in range(1, 100000):val *= iif __name__ == "__main__":l = []count = int(os.cpu_count())print(f"当前计算机CPU核心个数:{count}")start_time = time.time()for i in range(count):p = Process(target=task)p.start()l.append(p)for p in l:p.join()print(f"运行时间:{time.time() - start_time}")

【2】、多线程的使用

import os, timefrom threading import Threaddef task():val = 1for i in range(1, 100000):val *= iif __name__ == "__main__":l = []count = int(os.cpu_count())print(f"当前计算机CPU核心个数:{count}")start_time = time.time()for i in range(count):t = Thread(target=task)t.start()l.append(t)for t in l:t.join()print(f"运行时间:{time.time() - start_time}")

四、多线程的使用场景

  多线程 适合 IO 密集型 场景

【1】、多进程的使用

import timefrom multiprocessing import Processdef task():time.sleep(3)if __name__ == "__main__":l = []start_time = time.time()for i in range(1000):p = Process(target=task)p.start()l.append(p)for p in l:p.join()print(f"运行时间:{time.time() - start_time}")

【2】、多线程的使用

import timefrom threading import Threaddef task():time.sleep(3)if __name__ == "__main__":l = []start_time = time.time()for i in range(1000):t = Thread(target=task)t.start()l.append(t)for t in l:t.join()print(f"运行时间:{time.time() - start_time}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/494690.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue 92 ,Element 15 ,Vue + el-upload 实现图片上传与管理

目录 前言 一. 文章背景 二. 项目结构 三. 核心代码解析 1. 页面结构 2. 属性介绍 3. 必要参数 4. 函数逻辑 四. 相关样式布局 五. 关键功能解释 六. 注意事项 七. 本文总结 前言 在这篇博客中,我们将深入探讨如何使用 Vue 和 el-upload 构建一个图片上…

安宝特应用 | 美国OSHA扩展Vuzix AR眼镜应用,强化劳动安全与效率

随着工业技术的进步,如何在保障员工安全的同时提高生产效率成为现代企业面临的重要挑战。 美国劳工部职业安全与健康管理局(OSHA)于2024年12月2日宣布对Vuzix M400智能眼镜进行扩大部署,代表AR技术正为工业环境下的劳动保护开辟了…

linux socket编程之udp_dict_serve服务端--引入配置文件

注意:本篇博客只是对上一篇博客功能的增加 1.创建配置文件(翻译) Dict.txt apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 happy: 快乐的 sad: 悲伤的 run: 跑 jump: 跳 teacher: 老师 student: 学生 car: 汽车 bus: 公交车 love: 爱 hate: 恨 hell…

HTML基础学习(1)

目录 第一章、基础知识介绍1.1)基础知识介绍1.1.1)计算机介绍:硬件和软件1.1.2)架构介绍1.1.3)网站介绍 1.2)HTML基础介绍1.2.1)HTML创建网页文件与标签1.2.2)标签1.2.3)…

Android修行手册 - 移动端几种常用动画方案对比

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分…

MySQL 数据库优化详解【Java数据库调优】

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默, 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把…

初学stm32 --- NVIC中断

目录 STM32 NVIC 中断优先级管理 NVIC_Type: ISER[8]: ICER[8]: ISPR[8]: ICPR[8]: IABR[8]: IP[240]: STM32 的中断分组: 中断优先级分组函数 NVIC_PriorityGroupConfig 中断初始化函…

掌握命令行参数的艺术:Python的`argparse`库

文章目录 掌握命令行参数的艺术:Python的argparse库背景argparse库简介标准库中的重要性简单库函数使用方法场景应用常见Bug及解决方案总结 掌握命令行参数的艺术:Python的argparse库 背景 在Python编程中,我们经常需要从命令行接收参数来控…

如何根据一系列提交文件,匹配对应的git提交记录?用ai

显示提取提交文件记录的git历史(用的豆包写一下) 显示每次提交涉及的文件名及提交注释等基本信息 可以使用以下命令格式: git log --name-only --prettyformat:“%an - %s” myFolder/ –name-only选项的作用是在显示提交信息时&#xff0…

Redis篇--常见问题篇6--缓存一致性1(Mysql和Redis缓存一致,更新数据库删除缓存策略)

1、概述 在使用Redis作为MySQL的缓存层时,缓存一致性问题是指Redis中的缓存数据与MySQL数据库中的实际数据不一致的情况。这可能会导致读取到过期或错误的数据,从而影响系统的正确性和用户体验。 为了减轻数据库的压力,通常读操作都是先读缓…

探寻快速排序的局限性及其优化策略

一. 快速排序之局限 快速排序的平均时间复杂度为O(nlogn)。其核心步骤是:先从待排序数组中选定一个元素作为基准(pivot),通过一趟排序将数组分成两部分,使得左边部分的元素都小于等于基准元素,右边部分的元…

CS!GO

CS(computer science)计算机科学,说实话,不是找工作面试,这些题谁会背啊,反正我不行,一问三不知。 咱也不管这些,这个系列,可能会时不时的给出一些计网和操作系统相关的东…

python 内存管理

Python中的内存管理涉及包含所有Python对象和数据结构的私有堆。Python内存管理器在内部确保对此私有堆的管理。需要注意的是,Python堆的管理是由解释器本身执行的,并且用户无法控制它。从源码来看,分为以下几层: level 3&#xf…

Matlab个性化绘图第6期—带标记面的三维折线图

带标记面的三维折线图本质上就是多组折线图: Matlab论文插图绘制模板第92期—折线图(Plot) 或者三维折线图: Matlab论文插图绘制模板第37期—三维折线图(plot3) 不同之处在于带标记面的三维折线图把每一组数据单独放在一个三维平…

C/C++圣诞树

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C…

【C++语言】多态

一、多态的概念 多态的概念:通俗来说,就是多种形态,具体点就是去完成某种行为,当不同的对象去完成时会产生出不同的状态。 我们可以举一个例子: 比如买票这种行为,当普通人买票时,是全价买票&am…

GitCode 光引计划投稿|MilvusPlus:开启向量数据库新篇章

在人工智能和大数据时代,向量数据库作为处理非结构化数据的核心技术,正变得越来越重要。MilvusPlus,作为「光引计划」的一部分,应运而生,旨在提供一个高性能、易扩展、全功能的向量数据库解决方案。项目背景根植于对现…

Java设计模式 —— 【结构型模式】外观模式详解

文章目录 概述结构案例实现优缺点 概述 外观模式又名门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这…

Gin-vue-admin(1):环境配置和安装

目录 环境配置如果443网络连接问题,需要添加代理服务器 后端运行前端运行 环境配置 git clone https://gitcode.com/gh_mirrors/gi/gin-vue-admin.git到server文件目录下 go mod tidygo mod tidy 是 Go 语言模块系统中的一个命令,用于维护 go.mod 文件…

浅谈算法交易

本文想基于我的简单理解说说什么是算法交易,或者说是量化交易。 原文地址请访问:浅谈算法交易 什么是算法交易? 刚开始接触算法交易的时候,对它的理解,它就是把我平时的交易规则搬进计算机里自动执行。这个理解也没…