进程,线程,协程总结

2023-11-15

进程

在这里插入图片描述

三种状态

  1. 就绪态:运行的条件都已经慢去,正在等在cpu执行
  2. 执行态:cpu正在执行其功能
  3. 等待态:等待某些 条件满足,例如一个程序sleep了,此时就处于等待态

生命周期:

  1. 用户编写代码(代码本身是以进程运行的)

  2. 启动程序,进入进程“就绪”状态

  3. 操作系统调度资源,做“程序切换”,使得进程进入“运行”状态

  4. 结束/中断

特性

  1. 每个程序,本身首先是一个进程

  2. 运行中每个进程都拥有自己的地址空间、内存、数据栈及其它资源。

  3. 操作系统本身自动管理着所有的进程(不需要用户代码干涉),并为这些进程合理分配可以执行时间。

  4. 进程可以通过派生新的进程来执行其它任务,不过每个进程还是都拥有自己的内存和数据栈等。

  5. 进程间可以通讯(发消息和数据),采用 进程间通信(IPC) 方式。

说明

  1. 多个进程可以在不同的 CPU 上运行,互不干扰

  2. 同一个CPU上,可以运行多个进程,由操作系统来自动分配时间片

  3. 由于进程间资源不能共享,需要进程间通信,来发送数据,接受消息等

  4. 多进程,也称为“并行”。

  • 多进程
    • 函数方法:创建proess对象,指定target要执行的函数任务
    • 类方法:继承process,重写run方法,由这个类实例化之后执行start会自动调用run方法
      • 业务复杂是使用
  • 进程间通信
    • 进程队列queue

      • multiprocess.Queue
    • 管道pipe

    • 说明

    • 管道就是管道,就像生活中的管道,两头都能进能出

    • 默认管道是全双工的,如果创建管道的时候映射成False,左边只能用于接收,右边只能用于发送,类似于单行道

import multiprocessing

def foo(sk):
    sk.send('hello world')
    print(sk.recv())

if __name__ == '__main__':
    conn1,conn2=multiprocessing.Pipe()    #开辟两个口,都是能进能出,括号中如果False即单向通信
    p=multiprocessing.Process(target=foo,args=(conn1,))  #子进程使用sock口,调用foo函数
    p.start()
    print(conn2.recv())  #主进程使用conn口接收
    conn2.send('hi son') #主进程使用conn口发送

常用方法

conn1.recv():接收conn2.send(obj)发送的对象。如果没有消息可接收,recv方法会一直阻塞。如果连接的另外一端已经关闭,那么recv方法会抛出EOFError。
conn1.send(obj):通过连接发送对象。obj是与序列化兼容的任意对象
注意:send()和recv()方法使用pickle模块对对象进行序列化
  • 共享数据manage
    Queue和pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。
    注:进程间通信应该尽量避免使用共享数据的方式
  • 进程池
    • 开多进程是为了并发,通常有几个cpu核心就开几个进程,但是进程开多了会影响效率,主要体现在切换的开销,所以引入进程池限制进程的数量。
    • 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

僵尸进程与孤儿进程

  1. 僵尸进程是父进程早于子进程先退出,这种对操作系统有害
    • 如何避免:先执行一次fork在创建的子进程中再次fork,然后将第一次fork的进程退出,第二个子进程成为孤儿进程,从而其的父进程变为init进程,通过init进程管理,防止僵尸进程。
    • 通过信号机制异步回收,最理想处理方式
  2. 孤儿进程是父进程存在而不处理子进程,这种最终会交给pid处理

线程

线程,是在进程中执行的代码。

一个进程下可以运行多个线程,这些线程之间共享主进程内申请的操作系统资源。

在一个进程中启动多个线程的时候,每个线程按照顺序执行。现在的操作系统中,也支持线程抢占,也就是说其它等待运行的线程,可以通过优先级,信号等方式,将运行的线程挂起,自己先运行。

使用

用户编写包含线程的程序(每个程序本身都是一个进程)

操作系统“程序切换”进入当前进程

当前进程包含了线程,则启动线程

多个线程,则按照顺序执行,除非抢占

特性

线程,必须在一个存在的进程中启动运行

线程使用进程获得的系统资源,不会像进程那样需要申请CPU等资源

线程无法给予公平执行时间,它可以被其他线程抢占,而进程按照操作系统的设定分配执行时间

每个进程中,都可以启动很多个线程

说明

多线程,也被称为”并发“执行。

线程池

系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池。

线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致 Python 解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。

多线程通信

  • 共享变量
    创建全局变量,多个线程公用一个全局变量,方便简单。但是坏处就是共享变量容易出现数据竞争,不是线程安全的,解决方法就是使用互斥锁。

  • 变量共享引申出线程同步问题
    如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。 使用Thread对象的Lock和Rlock可以实现简单的线程同步,这两个对象都有acquire方法和release方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到acquire和release方法之间。

  • 队列
    线程间使用队列进行通信,因为队列所有方法都是线程安全的,所以不会出现线程竞争资源的情况

Queue.Queue 是进程内非阻塞队列

进程和线程的区别

一个进程中的各个线程与主进程共享相同的资源,与进程间互相独立相比,线程之间信息共享和通信更加容易(都在进程中,并且共享内存等)。

线程一般以并发执行,正是由于这种并发和数据共享机制,使多任务间的协作成为可能。

进程一般以并行执行,这种并行能使得程序能同时在多个CPU上运行;

区别于多个线程只能在进程申请到的的“时间片”内运行(一个CPU内的进程,启动了多个线程,线程调度共享这个进程的可执行时间片),进程可以真正实现程序的“同时”运行(多个CPU同时运行)。

进程和线程的常用应用场景

一般来说,在Python中编写并发程序的经验:

计算密集型任务使用多进程

IO密集型(如:网络通讯)任务使用多线程,较少使用多进程.

这是由于 IO操作需要独占资源

协程

协程: 协程,又称微线程,纤程,英文名Coroutine。协程的作用,是在执行函数A时,可以随时中断,去执行函数B,然后中断继续执行函数A(可以自由切换)。但这一过程并不是函数调用(没有调用语句),这一整个过程看似像多线程,然而协程只有一个线程执行.

协程由于由程序主动控制切换,没有线程切换的开销,所以执行效率极高。对于IO密集型任务非常适用,如果是cpu密集型,推荐多进程+协程的方式。

协程,又称微线程。

说明

协程的主要特色是:

协程间是协同调度的,这使得并发量数万以上的时候,协程的性能是远远高于线程。

注意这里也是“并发”,不是“并行”。

实现方式:greenlet gevent python之yield

协程优点:

1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级

2. 单线程内就可以实现并发的效果,最大限度地利用cpu

协程缺点:

1.协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程

2.协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进程,线程,协程总结 的相关文章

  • 2023年IT行业就业前景分析,准职场人必看!

    随着疫情的放开 2022已接近尾声 新的一年即将来临 作为打工人最关心的肯定是2023年的就业市场以及行业未来发展前景 如何最直观地看待这个行业是否还有前景 最好的方式就是看市场需求 作为准职场人的你 速速关注起来 根据智联招聘10月发布的
  • 进程,线程,协程总结

    进程 三种状态 就绪态 运行的条件都已经慢去 正在等在cpu执行 执行态 cpu正在执行其功能 等待态 等待某些 条件满足 例如一个程序sleep了 此时就处于等待态 生命周期 用户编写代码 代码本身是以进程运行的 启动程序 进入进程 就绪
  • python类的属性和实例的属性有什么区别

    在 Python 中 类属性和实例属性是两种不同类型的属性 它们在用途和作用域上有所不同 下面是关于它们的区别的详细解释 定义位置 类属性 定义在类的主体中 但在任何类方法之外 实例属性 通常在 init 方法或其他类方法中使用 self
  • 【python基础】:分类统计各字符的个数

    功能实现 利用python实现统计一个字符串中数字 字母及其他字符的个数和各个字符的总数 方法一 利用 isdigit isalpha 函数判断字符是否是数字或者字母 代码如下 s input 请输入一串字符 num char space
  • python从入门到放弃,学完python能做什么?

    首先python一门应用广泛的编程语言 所以无论是对于专业的程序员 还是从事其他工作的人 学会python都会增加自己的竞争力 那么 对于程序员或者其他职业的人 学会python具体都有些什么好处呢 一 如果程序员学会python 能做什么
  • 线程的三种实现方式

    一 继承Thread类 二 实现Runable接口 对于1 2两种方法应该都会知道的 即使在上java相关的课程中老师一般都会介绍这两种实现的方法 所以这里不赘述了 直接进入第三种第四种的实现方式 三 实现Callable接口 packag
  • Lua中的协程Coroutine

    一 协程是什么 1 线程 首先复习一下多线程 我们都知道线程 Thread 每一个线程都代表一个执行序列 当我们在程序中创建多线程的时候 看起来 同一时刻多个线程是同时执行的 不过实质上多个线程是并发的 因为只有一个CPU 所以实质上同一个
  • MFC之AfxbeginThread 线程 创建、挂起、释放、结束、退出

    MFC之AfxbeginThread 线程 创建 挂起 释放 结束 退出 本文简单阐述了如何使用一个afxbeginthread创建一个线程 两种方法 使用默认设置 使用自主设置参数 以及一些如同 挂起 释放 边界锁等操作 h文件添加声明
  • Mysql数据库的环境搭建【详细】

    作者简介 大学机械本科 野生程序猿 学过C语言 玩过前端 还鼓捣过嵌入式 设计也会一点点 不过如今痴迷于网络爬虫 因此现深耕Python 数据库 seienium JS逆向 安卓逆向等等 目前为全职爬虫工程师 学习的过程喜欢记录 目前已经写
  • python--socket(套接字/插口)

    socket是什么 是进程间通信的一种方式 它与其他进程间通信的一个主要不同是 它能实现不同主机之间的进程通信 我们网络上各种各样的服务大多都是基于socket来完成通信的 例如我们浏览网页 qq聊天 收发emil Socket是应用层与T
  • QT在子线程发送信号给主线程,主线程信号槽函数没有反应的解决办法

    在编写线程时遇到了一个问题 即子线程发送信号给主线程 主线程信号槽函数没有反应 这个问题卡了半天 最终找到解决办法 自己记录一下 问题 在子线程的run函数发送了一个信号 在主函数中定义了一个信号槽函数用来响应这个信号 但是槽函数不执行 修
  • 相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。

    题目描述 相传韩信才智过人 从不直接清点自己军队的人数 只要让士兵先后以三人一排 五人一排 七人一排地变换队形 而他每次只掠一眼队伍的排尾就知道总人数了 输入3个非负整数a b c 表示每种队形排尾的人数 a lt 3 b lt 5 c l
  • python opencv卡尺测量边缘距离

    opencv 卡尺法 测量边缘距离 参考来源 https github com crackwitz metrology demo 前言 一 测量方法 二 测量步骤 1 获取直线的像素 2 高斯滤波平滑曲线 3 计算跳变幅度值 4 计算距离值
  • python--- end=“ , 单独的一行print()是什么意思

    有如下一道练习题 编写代码打印出下列图形 代码如下 for i in range 4 for j in range 5 print end print 其中end 意思是为末尾end传递一个空字符串 这样print函数不会在字符串末尾添加一
  • sem_init函数用法

    sem init函数 sem init函数是Posix信号量操作中的函数 sem init 初始化一个定位在 sem 的匿名信号量 value 参数指定信号量的初始值 pshared 参数指明信号量是由进程内线程共享 还是由进程之间共享 如
  • python--模块导入

    目录 模块简介 模块导入的两种方式 方式一 import 方式二 from import 模块简介 1 什么是模块 模块就是一系列功能的结合体 可以直接使用 2 为什么要用模块 极大地提升开发效率 拿来主义 gt gt gt 站在巨人的肩膀
  • R基础(一)- R版本升级、现有版本查看

    R版本升级 系统 WINDOWS 方式 推荐打开RGui界面进行升级 而不要再RStudio中直接输入命令 包 installr 代码 安装包 如果已经有此包可跳过此步骤 install packages installr 加载包 升级 l
  • python基础之数据类型知识(1)

    注释 注解 解释 说明文字而已 特征 注释只是用于说明的文字不会影响内容本身 作用 1 用于添加说明文字 方便阅读 2 用于调试程序 排查错误 分类 单行注释 多行注释 内容 或者 内容 代码 print hello world print
  • python自学篇十五[Numpy——基础(一):(jupyter Notebook+Anaconda+conda+jupyter配置及简单操作 ]

    文章目录 概括 Numpy Scipy pandas matplotlib 一 Numpy 基础 1 jupyter Notebook 1 安装Anaconda 2 Anaconda是什么 1 Anaconda Navigator 2 Ju
  • 进阶之Kotin协程原理和启动方式详细讲解(优雅使用协程)

    协程就是方法调用封装成类线程的API 方法调用当然比线程切换轻量 而封装成类线程的API后 它形似线程 可手动启动 有各种运行状态 能够协作工作 能够并发执行 前言 kotlin的协程在初学者看来是一个很神奇的东西 居然能做到用同步的代码块

随机推荐

  • MATLAB--卡尔曼滤波

    利用matlab来实现卡尔曼滤波 一个简单的例子 clear all clc close all 利用卡尔曼滤波算法来估计状态值 定义状态转移矩阵和观测矩阵 syms x u h x x exp x 3 2 x 2 H diff h x f
  • nodejs服务器响应头,nodejs-getpost提交http请求响应

    理解表单使用post方式提交数据时后端接收数据的方法 理解表单使用get方式提交数据时后端接收数据的方法 理解post和get的区别 记住请求报文的组成 记住响应报文的组成 fs模块 进行目录和文件操作 readFile 读文件 write
  • Java+seleinum+IDEA环境搭建

    本机Win7 64位 chrome36 IDEA Java 8 selenium3 1 安装Java 本地安装Java8的jdk 配置环境变量 具体方法自己百度 2 安装IDEA 默认安装即可 3 安装selenium及驱动 a 下载sel
  • python append 覆盖数据

    更多文章详见 python append 覆盖数据 自我的进化https www shanxing top p 205 问题 使用append为list添加object的时候 有时候会出现后面的object将前面的几个给覆盖的情况 原因 当
  • QT里的网络通信简介

    QTcpSocket类简介 QTcpSocket类提供了一个TCP套接字 TCP 传输控制协议 是一种可靠的 面向流的 面向连接的传输协议 它特别适合数据的连续传输 QTcpSocket是QAbstractSocket的一个子类 它允许您建
  • 图像分割评价指标: Dice, MIoU, MPA等

    目录 1 混淆矩阵 2 Dice 3 MIoU 4 MPA 仅为个人结合一些博客的理解 1 混淆矩阵 如果是k 1分类问题 就会生成 k 1 k 1 的混淆矩阵 具体定义可参见百度百科 下面以肺结节分割为例 显然这是一个二分类的问题 肺结节
  • 菜鸟求职记1

    熬过了黑色的六月 我和往届的学长学姐一样 背着书包 拎着行李箱 开始了XV的求职之路 忙里偷闲 今天没有招聘会 一整天都在寝室 想着这几天的忙碌身影 我觉着应该将此点滴记录下来 以激励我以后的人生 9月10日 我们早上5点多开始从延安赶往西
  • Tornado 多进程分析(转载)

    引子 Tornado 是一个网络异步的的web开发框架 并且可以利用多进程进行提高效率 下面是创建一个多进程 tornado 程序的例子 usr bin env python coding utf 8 import os import ti
  • webpack5 基础配置(7) eslint-ts的使用和在webpack中的配置 加载vue文件

    上一节最后讲到了typescript的使用 ts loader本质上也是利用与tsc 所以安装ts loader的同时需要安装typescript 如果你没安装typescript 在你安装ts loader的时候 会根据ts loader
  • Git回退分支到某版本

    1 找到要回退的版本号 TortoiseGit gt Show Log gt 选中要回退的版本 gt Reset xxx to this gt commit旁复制版本号 2 本地回退到某版本 git reset hard 9224ad994
  • Idea 中 Docker 的 log 乱码

    IDEA 本地调试代码中英文显示全部正常 但是用 idea 中的 docker 插件部署到服务器 再查看 容器中 log 的时候 log 里面的中文全是乱码 就开启了一段排查过程 开始一个个排查 程序员的日常 查看容器中语言 字符集 环境
  • 【Android】java.lang.UnsatisfiedLinkError: No implementation found for void xx xx xx -- 问题解决

    Android在开发过程中总会出现各种各样的bug 要想畅通无阻的完成一个app的 开发工作固然有点难度 这不 我的程序跑着跑着又报错了 AndroidRuntime FATAL EXCEPTION Thread 4903 Process
  • 反汇编二进制代码

    最近又做了一些内核hook的工作 繁琐的地方在于二进制指令的可读性上 下面简要记录dump出指令二进制 之后利用binutils来转成可读的汇编代码 hook的主要流程参考之前的linux内核态hook模块 splice 主要就是构建一个t
  • 理解MySQL回表

    回表就是先通过数据库索引扫描出数据所在的行 再通过行主键id取出索引中未提供的数据 即基于非主键索引的查询需要多扫描一棵索引树 因此 可以通过索引先查询出id字段 再通过主键id字段 查询行中的字段数据 即通过再次查询提供MySQL查询速度
  • Java编程——输出1000以内的素数(质数)

    素数的定义是什么 质数 prime number 又称素数 有无限个 一个大于1的自然数 除了1和它本身外 不能被其他自然数 质数 整除 换句话说就是该数除了1和它本身以外不再有其他的因数 否则称为合数 public class demo7
  • STM32库函数TIM_SetCompare()的工作机制测试

    一 TIM SetCompare 函数的定义 其中 TIM SetCompareX 这个函数有四个 它们为 TIM SetCompare1 TIM SetCompare2 TIM SetCompare3 TIM SetCompare4 同时
  • 引脚悬空是什么电平_STM32单片机必须掌握的八种IO口模式和引脚配置方式

    八种IO口模式 STM32有八种IO口模式 分别是 模拟输入 浮空输入 上拉输入 下拉输入 开漏输出 推挽输出 复用开漏输出和复用推挽输出 1 模拟输入 GPIO Mode AIN模拟输入 即关闭施密特触发器 将电压信号传送到片上外设模块
  • 关于STM32F103 TIM2重映射

    关于STM32F103 TIM2重映射 如何使用重映射和如何重映射为哪些管脚 这里不详细讲解 可以百度找到 下面讲的是tim2重映射为PA15 PB3 PB10 PB11 这里的设置网上也有讲解 但是如果功能较为复杂的程序 外设用的比较多的
  • 黑马JVM总结(五)

    1 方法区 它是所有java虚拟机 线程共享的区 存储着跟类的结构相关的信息 类的成员变量 方法数据 成员方法 构造器方法 特殊方法 类的构造器 方法区在虚拟机启动时被创建 方法区逻辑上是堆的组成部分 但是不同的JVM厂商实现是不一样的 O
  • 进程,线程,协程总结

    进程 三种状态 就绪态 运行的条件都已经慢去 正在等在cpu执行 执行态 cpu正在执行其功能 等待态 等待某些 条件满足 例如一个程序sleep了 此时就处于等待态 生命周期 用户编写代码 代码本身是以进程运行的 启动程序 进入进程 就绪