由浅入深走进Python异步编程【多进程】(含代码实例讲解 || multiprocessing、异步进程池、进程通信)

写在前面

从底层到第三方库,全面讲解python的异步编程。这节讲述的是python的多线程实现,纯干货,无概念,代码实例讲解。

本系列有6章左右,点击头像或者专栏查看更多内容,陆续更新,欢迎关注。

部分资料来源及参考链接:
https://www.bilibili.com/video/BV1Li4y1j7RY/

multiprocessing(多进程)

现在让我们初步进入多进程,这个就是python的多进程包,是自带的,简单示例:

import multiprocessing#进程包
import time

def start():
   time.sleep(2)#让程序沉睡 2 秒
   print(multiprocessing.current_process().name)#打印进程名字
   print(multiprocessing.current_process().pid)#打印pid
   print(multiprocessing.current_process().is_alive())#打印进程是否活着

if __name__ == "__main__":
   print('程序开始')
   p = multiprocessing.Process(target = start)#只用写函数名  不要加括号
   p.start()#开始
   p.join()#堵塞
   print('程序结束')

此时,并不是一个进程打开多个线程,而是多个进程,所以每次执行有不同的pid。

结果如下:
在这里插入图片描述

进程通信

本身进程是无法通信的,借助别的数据结构,就可以实现进程通信了,一般是栈和队列,就像这样:

from multiprocessing import Process,Queue

def write(q):#放入队列

    print('加入队列成功:{}'.format(Process.pid))#打印进程pid

    for i in range(10):# 0~9
        print('往队列放入:{}'.format(i))
        q.put(i)#放入

def read(q):#读取队列

    print('加入队列成功:{}'.format(Process.pid))#打印进程pid

    while True:#一有东西 就马上读取
        value = q.get()#读取
        print('获取队列中的东西:{}'.format(value))


if __name__ == "__main__":
    
    #由于Python的多进程默认无法进行通信   因为是并发执行的
    #所以要借助别的数据结构 
    #一般用栈 或者 队列
    q = Queue()#实例化Queue   队列
    pw = Process(target = write,args =(q,))#创建写入进程
    pr = Process(target = read,args = (q,))#创建读取进程
    pw.start()#启动写入
    pr.start()#启动读取

    pw.join()#堵塞读取

python当中实现了栈和队列,非常方便,如果你运行上述代码,你会发现程序没有结束,读取进程它还在反复读取。这其实就和golang中的管道类似。此处可以先做了解。

进程池

可以使用map方法批量提交目标

import multiprocessing

def index_pool(data):
    res = data * data
    return res

if __name__ == "__main__":

    data =  list(range(100))#100个任务 
    pool = multiprocessing.Pool(processes = 4)#进程池大小为4

    pool_out_puts = pool.map(index_pool,data)#一次性提交大量任务
    # pool_out_puts = pool.apply(index_pool,args=(10,))#一个个提交
    pool.close()#关闭进程  不再创建进程
    pool.join()#堵塞进程
    
    print('Pool    {}'.format(pool_out_puts))

运行结果:
在这里插入图片描述

你会发现执行速度非常快

为什么进程池这么快呢?

这就是与多线程的区别,每个进程是独立的,不会受到GIL锁的控制,速度非常快

异步进程池

上述的例子中,进程是同步执行的,如何写出异步的效果呢?

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor,as_completed
import time

number_list = [1,2,3,4,5,6,7,8,9,10]

def add_number(data):#这个函数  只能消耗CPU资源  没啥意义

    item = count(data)
    return item

def count(number):#单纯计算  随便写

    for i in range(0,5000000):
        i = i + 1

    return i * number

if __name__ == "__main__":
    
    start_time = time.time()#程序启动时间

    with ProcessPoolExecutor(max_workers = 5) as t:# max_workers参数为 你要开多少个进程

        for item in number_list:#提交任务 
            t.submit(add_number,item)

        # reqs = [t.submit(add_number,item) for item in number_list]#提交任务 简洁写法
        # for req in as_completed(reqs):# 转成 可迭代对象
        #     print(req.result())#打印信息

    print('程序总耗时:{}'.format(time.time() - start_time))

由于没有GIL锁的限制,执行会非常快。

进程池和异步进程池的区别是什么呢?

在Python中,进程池(Process Pool)和异步进程池(Asyncio Process Pool)是用于并行处理任务的两种不同的机制。

进程池(Process Pool):
进程池是通过multiprocessing模块提供的一种机制,它允许你创建一组预先初始化的进程,用于执行任务。你可以将任务提交给进程池,进程池会自动分配可用的进程来执行任务。进程池可以通过Pool类来创建。
进程池适用于CPU密集型任务,可以充分利用多核处理器的并行性。它通过创建多个进程来同时执行任务,每个进程都有自己的Python解释器和GIL,因此可以实现真正的并行执行。进程池在处理大量计算密集型任务时通常具有较好的性能。

异步进程池(Asyncio Process Pool):
异步进程池是通过concurrent.futures和asyncio模块提供的一种机制,它允许在异步环境中并行处理任务。异步进程池是建立在异步编程的基础上,可以在单个线程中同时执行多个任务。
异步进程池适用于IO密集型任务,如网络请求、文件读写等。它利用异步编程的特性,通过在任务之间进行切换来提高效率,避免了线程切换的开销。异步进程池在处理大量IO密集型任务时通常具有较好的性能。

进程池和线程池处理IO密集型的任务都很快吗?

异步线程池和异步进程池的主要区别在于线程池使用的是线程,而进程池使用的是进程。

线程池:在Python中,线程是由操作系统管理的,多个线程共享同一进程的内存空间,因此线程之间的切换开销较小。线程池适用于IO密集型任务,如网络请求、文件读写等,因为在这些任务中,大部分时间都是在等待IO操作完成,线程可以在等待期间切换执行其他任务,提高效率。

进程池:进程是由操作系统管理的,每个进程都有独立的内存空间,进程之间切换的开销较大。进程池适用于CPU密集型任务,如数据处理、图像处理等,因为这些任务需要大量的计算资源,多个进程可以并行执行,提高效率。

无论是线程池还是进程池,在处理IO密集型任务时都可以提高效率。但对于CPU密集型任务,由于Python的全局解释器锁(GIL)的存在,多线程并不能真正实现并行执行,因此在这种情况下使用进程池更为合适。如果需要同时处理大量IO密集型和CPU密集型任务,可以结合使用线程池和进程池来充分利用多核资源。

为什么不直接用进程池呢?

进程会特别占用内存,能够使用线程池的场景,还是使用线程池更好。

用实例解释进程池和异步进程池的区别

以网络爬虫为例:
当使用进程池和异步进程池来实现网络爬虫项目时,它们的处理逻辑和性能表现有一些区别。

使用进程池的处理逻辑如下:

  1. 创建一个进程池对象,设置进程数为10。
  2. 将待爬取的URL列表分成若干个子任务,每个子任务包含多个URL。
  3. 使用进程池的map()方法,将子任务提交给进程池。
  4. 进程池会自动将子任务分配给空闲的进程进行处理,每个进程负责处理一个子任务。
  5. 当所有子任务都完成时,进程池会返回结果,可以通过返回的结果来获取爬取的数据。

使用异步进程池的处理逻辑如下:

  1. 创建一个异步进程池对象,设置进程数为10。
  2. 将待爬取的URL列表分成若干个子任务,每个子任务包含多个URL。
  3. 使用异步进程池的submit()方法,将每个子任务提交给异步进程池。
  4. 异步进程池会立即返回一个Future对象,表示该子任务的执行状态。
  5. 可以通过Future对象的result()方法来获取子任务的结果,如果子任务还未完成,result()方法会阻塞等待直到结果可用。
  6. 可以使用concurrent.futures.as_completed()函数来迭代Future对象,获取已完成的子任务结果。

在性能方面,异步进程池通常比进程池更快。这是因为异步进程池可以同时执行多个任务,不需要等待一个任务完成后才能执行下一个任务,从而提高了效率。而进程池则需要按顺序逐个处理任务,无法并行执行。对于IO密集型的任务,异步进程池的性能提升更为明显,因为它可以充分利用CPU等待IO的时间来执行其他任务。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

群多多社群人脉H5-2.1.4多开插件+小程序独立前端+搭建教程

功能介绍: 1、群多多社群大全,是一个集发布、展示社群信息、人脉推广的裂变工具/平台。 2、通过人脉广场,将商家信息通过名片进行展示,让资源对接、人脉推广更加便捷高效。 3、行业群、兴趣群、知识付费群、交友群、商家活动推…

DMA实验3-外设到内存搬运

实验要求 使用 DMA 的方式将串口接收缓存寄存器的值搬运到内存中,同时闪烁 LED1 。 CubeMX 配置 DMA 配置: 串口中断配置 代码实现 如何判断串口接收是否完成?如何知道串口收到数据的长度? 使用串口空闲中断(IDL…

十一、W5100S/W5500+RP2040之MicroPython开发<MQTT阿里云示例>

文章目录 1. 前言2. 平台操作流程3. WIZnet以太网芯片4. 示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代,MicroPython和树莓派PICO正以其独特的优势引领着嵌入式开发…

谷歌 | Duet AI 让洞察、聚类模型和可视化变得简单

迷失在数据的海洋 我们都经历过这样的情况:淹没在数据的海洋中,努力驾驭复杂的管道,感觉数据令人头晕。管理大量充满不同工具和 Google 搜索的选项卡以及花费大量时间筛选数据和代码以创建满足您需求的模型所带来的挫败感,真的会…

探索UX设计师的日常任务,赶紧看看

UX 设计师专注于产品开发的各个方面,包括设计、可用性、功能、甚至品牌和营销。他们的工作涉及用户与产品交互的整个端到端旅程,包括为产品和业务识别新的机会。 鉴于他们广泛的范围,UX 设计师根据公司和项目的要求,执行多种不同…

探索 MajicStudio:一款多功能视频编辑软件

一、产品简介 MajicStudio是一款基于人工智能的图片编辑与设计工具,拥有简洁的界面与丰富功能。采用深度学习和计算机视觉技术可以自动识别图片要素。 二、应用场景 MajicStudio的AI图像功能适用于多场景,包括艺术设计、电商、游戏和文创等场景。 三…

【Proteus仿真】【Arduino单片机】蓝牙遥控小车

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器,使LCD1602液晶,L298电机,直流电机,HC05/06蓝牙模块等。 主要功能: 系统运行后,LCD1602…

数据结构和算法笔记2:二分法

二分法网上有两种写法&#xff0c;一种左闭右闭&#xff0c;一种左闭右开&#xff0c;个人习惯左闭右闭的写法&#xff0c; 有序数组查找数 这是标准二分法&#xff0c;对应力扣的704. 二分查找&#xff1a; 求值为target的索引 int search(vector<int>& nums, i…

Thread类的基本用法

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; Thread 1. 线程创建1.1 继承Thread类1.2 实…

arcEngine修改字段标注

修改字段标注 在arcEngine中&#xff0c;有时候需要修改图层要素的标注值&#xff0c;而且每个字段值对应了要修改的内容&#xff0c;如字段值”1“替换成”A“&#xff0c;字段值”2“替换成”B“等&#xff0c;这就需要在替换的图层中&#xff0c;遍历每个要素&#xff0c;查…

LeetCode 21 合并两个有序链表

题目描述 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [],…

「用户与社区的深度对话」2023年度IvorySQL满意度调研

致IvorySQL社区成员&#xff0c; &#x1f3c3;‍♂️2023年即将进入尾声&#xff0c;感谢每一位社区朋友对IvorySQL的支持。我们诚挚地邀请您参与我们的社区满意度调研。您的反馈对我们至关重要&#xff0c;将有助于改进我们的服务&#xff0c;为您提供更好的社区体验&#xf…

[数据结构进阶 C++] 二叉搜索树(BinarySearchTree)的模拟实现

文章目录 1、二叉搜索树1.1 二叉搜索数的概念1.2 二叉搜索树的操作1.2.1 二叉搜索树的查找1.2.2 二叉搜索树的插入1.2.3 二叉搜索树的删除 2、二叉搜索树的应用2.1 K模型2.2 KV模型 3、二叉搜索树的性能分析4、K模型与KV模型完整代码4.1 二叉搜索树的模拟实现&#xff08;K模型…

设计模式(三)-结构型模式(6)-享元模式

一、为何需要享元模式&#xff08;Flyweight&#xff09;? 假如在网页中渲染这样的一个画面&#xff1a;大小不一的星星铺满了整个画布&#xff0c;并且都在不断的进行移动闪烁着。一批星星消失了&#xff0c;另一批又从另一边缘处出现。 要实现这样的渲染效果&#xff0c;在…

C语言之初识C语言

文章目录 前言一、什么是C语言二、第一个C语言程序三、数据类型四、变量&#xff0c;常量1、变量1.1 变量的命名1.2 变量的分类1.3 变量的使用1.4 变量的作用域和生命周期2、变量 五、字符串1. 概念2. 求解字符串的长度【strlen】3. 转义字符【含笔试题】 六、注释七、选择语句…

ESP8266 TCP/串口透传

简介 先在PC上做测试, 使用串口软件对ESP8266 模块进行设置, 使用网络助手软件与串口软件进行自由收发设置 ATRST ## 复位 ATCWMODE_DEF1 ## 设置为Station模式 ATCWJAP_DEF“路由器wifi名称”,“路由器wifi密码” ## 设置ESP连接的路由器名称密码 ATCIPSTART“TCP”,“192.1…

Alpha突触核蛋白神经退行性疾病

Alpha突触核蛋白科研背景 ● Alpha突触核蛋白约 15kDa, 140个氨基酸 ● StressMarq在E. coli中过表达人源基因然后将蛋白从细胞质基质中纯化出来 ● 未折叠的alpha突触核蛋白单体在12% SDS-PAGE上为~15 kDa的条带 StressMarq/欣博盛生物的Alpha突触核蛋白有以下两类&#xf…

[uni-app] mescroll与 page 本身的滚动冲突处理, 动态禁用下拉刷新

参考贴: uniapp动态禁用mescroll-body组件的下拉刷新,或者动态禁用mescroll-body组件的上拉加载 记录问题场景 如图: 搜索和 第二个标签栏, 都是随页面滚动的, 当页面滚动一定距离, 会触发标签栏的吸顶 即如上图, 问题描述 当列表页面数据部满屏时, 且页面已经由于滚动而吸顶…

许可式邮件营销与垃圾邮件的区别:合规与效果的关键区分

接触过邮件营销的人一定不陌生“垃圾邮件”和“许可式邮件营销”这两个名词。在各大电商节到来之际&#xff0c;小编帮助大家弄清楚什么是垃圾邮件&#xff1f;什么是许可式邮件营销&#xff1f;为什么会变成垃圾邮件&#xff1f;怎么做许可式邮件营销&#xff1f;让大家在促销…

极智嘉(Geek+)货到人方案优势显著,助力拆零场景效率提升

众所周知&#xff0c;零售行业所面临的物流挑战比其他行业更为严峻。这是由于零售行业复杂的行业业态、繁多的商品种类、“唯快主义”的配送需求&#xff0c;以及零售行业的终端客户多为个体消费者&#xff0c;购买习惯以单件、多品为主&#xff0c;购买习惯具有周期性和爆发性…