Python多进程笔记(Python_MultiProcess)

2023-05-16

1. MutiProcessing(多进程)使用:

a. 什么是多进程?

在上面我们使用多线程去分别处理不同的事情,看起来,多线程处理并不比单线程循环处理的效率看起来那么的高。多进程是在利用我们电脑CPU多核的特性,去提高我们处理多个事情的效率。

b. 创建一个进程:

创建一个进程我们需要先导入涉及到进程的模块import multiprocessing as mp

进程拥有类似线程的方法。举个例子如下:

import multiprocessing as mp

def job(a, b):
    print(a + b)

if __name__ == '__main__':
    p1 = mp.Process(target= job, args = (1, 2))
    p1.start()
    p1.join()

c. 多进程中的Queue的使用:

在上面提到的多线程中使用Queue来保存工作结果以及多个线程之间的通信。在多进程中,Queue的作用依然是保存工作结果以及进行通信。让我们看下面例子来使用Queue保存result,如下:

import multiprocessing as mp

def job(q):
    res = 0
    for i in range(1000):
        res += i + i ** 2 + i ** 3
    q.put(res)

if __name__ == '__main__':
    q = mp.Queue()
    p1 = mp.Process(target= job, args = (q, )) #注意这里的args即使只有一个参数,也必须加上逗号,表示这个参数是一个可迭代的对象
    p2 = mp.Process(target= job, args = (q, ))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    res1 = q.get()
    res2 = q.get()
    print('Process1 compute result1: %d' % res1)
    print('Process2 compute result2: %d' % res2)

d. 多线程与多进程以及正常处理的效率对比:

请看以下例子,我们使用双核来测试,创建两个进程,创建两个线程,在单线程进行两次循环,进行相同的job。比较三者的效率可发现多进程在计算上会优于多线程以及普通方法。而由于GIL的存在,多线程看起来是分配Job给不同的线程进行处理,但是在数量级大的操作上,他会因为在单核中切换线程耗费不少时间。因此,多线程的处理效果往往不如单线程的循环操作。例子如下:

import multiprocessing as mp
import threading as tp
import time
def job(q):
    res = 0
    for i in range(1000000):
        res += i + i ** 2 + i ** 3
    q.put(res)

def MultiProcessJob():
    q = mp.Queue()
    p1 = mp.Process(target= job, args = (q, )) #注意这里的args即使只有一个参数,也必须加上逗号,表示这个参数是一个可迭代的对象
    p2 = mp.Process(target= job, args = (q, ))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    res1 = q.get()
    res2 = q.get()
    print('Process1 compute result1: %d' % res1)
    print('Process2 compute result2: %d' % res2)

def MultiThreadJob():
    q = mp.Queue()
    t1 = tp.Thread(target= job, args = (q, )) #注意这里的args即使只有一个参数,也必须加上逗号,表示这个参数是一个可迭代的对象
    t2 = tp.Thread(target= job, args = (q, ))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    res3 = q.get()
    res4 = q.get()
    print('Thread1 compute result3: %d' % res3)
    print('Thread2 compute result4: %d' % res4)

def NormalJob():
    res = 0
    for i in range(2):
        for j in range(1000000):
            res += i + i ** 2 + i ** 3
    print('Normal compute result5: %d' % res)

if __name__ == '__main__':
    st = time.time()
    NormalJob()
    ft = time.time()
    print('Normal Time is:', ft - st)
    st1 = time.time()
    MultiThreadJob()
    ft1 = time.time()
    print('MultiThread Time is', ft1 - st1)
    st2 = time.time()
    MultiProcessJob()
    ft2 = time.time()
    print('MultiProcess Time is', ft2 - st2)
'''
result:
Normal compute result5: 3000000
Normal Time is: 1.0905730724334717
Thread1 compute result3: 249999833333583333000000
Thread2 compute result4: 249999833333583333000000
MultiThread Time is 1.2889320850372314
Process1 compute result1: 249999833333583333000000
Process2 compute result2: 249999833333583333000000
MultiProcess Time is 0.668349027633667
'''

e. 进程池Pool的使用:

进程池是给我们自动的分配计算机中CPU多核资源进行计算,比如你要使用4个进程去分别处理相同的job,手动则需要建立四个Process,会比较麻烦。所以引入进程池创建进程使用CPU多核资源相当简便。

Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。
参考下面代码

import multiprocessing as mp

def job(x) :
    return x * x

def multiProcess():
    pool = mp.Pool(processes = 4) #利用4核处理
    res = pool.map(job, range(100)) #将结果map组合起来
    print(res)
    res = pool.apply_async(job, (2, )) #apply_async方法是异步阻塞,不用等待当前进程执行完毕,随时根据系统调度来进行切换
    print(res.get())
    multi_res = [pool.apply_async(job, (i, )) for i in range(100)]
    print([res.get() for res in multi_res])

if __name__ == '__main__':
    multiProcess()

f. 共享内存以及进程锁(shared memory & lock)

共享内存的意思是,你的计算机CPU有多核处理器,假设我们的CPU是一个四核处理器,我们想让Process1去计算完一个变量,然后我们想让Process2在这个变量上继续进行操作。那么我们就要使用共享内存。使用multiprocessing.Value(‘i’, int类型的数值).之所以使用lock是保证各个进程之间单独执行完,不会发生抢占式对共享内存中的数据进行修改。例子如下:

import multiprocessing as mp
import time

def job(v, num, lock):
    lock.acquire()
    for i in range(10):
        time.sleep(0.2)
        v.value += num
        print(v.value)
    lock.release()

def multiProcess():
    lock = mp.Lock()
    v = mp.Value('i', 0)
    p1 = mp.Process(target=job, args=(v, 10, lock))
    p2 = mp.Process(target=job, args=(v, 100, lock))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

if __name__ == '__main__':
    multiProcess()

这个Code主要是给定两个进程同时对共享内存中的数据操作,Process1进行add 10, Process2进行add 100.通过lock锁控制各个进程的compute互不干扰。

Code欢迎给个star

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

Python多进程笔记(Python_MultiProcess) 的相关文章

随机推荐

  • 免登陆Oracle官网下载JDK

    Oracle官网下载JDK 方法一 免登录下载 进入官网 xff0c 选择需要下载的JDK版本 xff0c 这里以JDK8为例 点击下载 xff0c 勾选同意 在正常情况下 xff0c 点击 Download jdk 8u333 windo
  • linux rancher 清理docker容器磁盘空间

    目录说明 var lib docker containers xff1a 是 Docker 在 Linux 系统上默认存储容器信息的目录 在该目录下 xff0c 每个运行的 Docker 容器都有一个单独的目录 xff0c 以容器 ID 命
  • 如何在官网下载COCO数据集

    官网地址 xff1a https cocodataset org download 1 选择下载的数据 xff0c 右键 xff0c 获取下载地址 2 将 http 改为 https 示例获得的下载地址为 xff1a http images
  • 两个互相引用对象的垃圾回收

    部分转自 xff1a 深入理解java虚拟机 一书 判断对象是否存活 1 引用计数算法 给对象添加一个引用计数器 xff0c 每当有一个地方引用它时 xff0c 计数器值就加1 当引用失效时 xff0c 计数器值就减1 任何时刻计数器为0的
  • ssm整合时,通过jdbc.properties文件无法连接mysql问题

    最近在重温ssm框架 在搭建基础的项目进行单元测试时 xff0c 发现无法连接mysql数据库 通过各种查资料终于发现了原因 原始jdbc properties文件 由于username这个属性会被系统的username变量覆盖 xff0c
  • Mysql数据库之左连接left join 右连接right join 内连接inner join

    最近 xff0c 公司的用户达到了700 43 万 xff0c 意味着数据库已经达到700 43 万 xff0c 聊聊傻傻分不清的连接查询吧 xff01 前提 数据库中一共有三个表 class book phone 而且每个数据库表中都有1
  • VMware虚拟机软件,配置Linux Ubuntu操作系统环境,及安装问题总结大全

    文章目录 1 xff1a 前言2 xff1a 基本认识3 下载环境4 xff1a VM虚拟机的安装5 xff1a ubuntu的下载6 xff1a 把ubuntu安装在VM虚拟机上7 VMware Tools工具8 Source insig
  • linux常用命令(Beginner note)

    命令 ls 列出所有文件及文件夹 ls 路径 xff1a 列出所给路径下的所有文件及文件夹 选项 xff1a xff08 可组合使用 xff0c 也可简写组合形式 xff0c 例 xff1a alh xff0c 无先后顺序 xff09 a
  • 利用JS-SDK微信分享接口调用(后端.NET)

    一直都想研究一下JS SDK微信分享的接口调用 xff0c 由于最近工作需要 xff0c 研究了一下 xff0c 目前只是实现了部分接口的调用 xff1b 其他接口调用也是类似的 xff1b 在开发之前 xff0c 需要提前准备一个微信公众
  • Linux文件查找find

    1 find查找概述 为什么要有文件查找 xff0c 因为很多时候我们可能会忘了某个文件所在的位置 xff0c 此时就需要通过find来查找 find命令可以根据不同的条件来进行查找文件 xff0c 例如 xff1a 文件名称 文件大小 文
  • Linux文件打包与压缩

    1 文件打包与压缩 1 什么是文件压缩 将多个文件或目录合并成为一个特殊的文件 比如 搬家 脑补画面 img 2 为什么要对文件进行压缩 xff1f 当我们在传输大量的文件时 xff0c 通常都会选择将该文件进行压缩 xff0c 然后在进行
  • 集中式版本管理SVN与分布式版本管理Git的区别

    集中式版本控制系统SVN CVS 先说集中式版本控制系统 xff0c 版本库是集中存放在中央服务器的 xff0c 而大家工作的时候 xff0c 用的都是自己的电脑 xff0c 所以要先从中央服务器取得最新的版本 xff0c 然后开始工作 x
  • chatgpt Linux 定时任务 清理rancher pod启动服务的日志文件 脚本

    Linux 定时任务执行命令 假设我们想要每隔X分钟 每隔X天 每天X点执行一个脚本文件 xff0c 可以使用 Linux 自带的 cron 工具来创建定时任务 清理步骤 您可以使用 Linux 自带的 cron 工具来创建定时任务 xff
  • Http协议的几种常见状态码

    在开发好了网站后 xff0c 用户通过URL对资源进行操作 xff0c 服务器端要告诉用户交互的结果 xff0c 比如新增资源是成功还是失败了 一个较好的办法就是遵循HTTP协议 xff0c 使用请求响应的HTTP状态码 xff08 Sta
  • 推荐画UML图以及流程图的在线网站Site

    记得当年学UML课程的时候 xff0c 当你还在为了安装Rose而发愁的时候 xff0c 人家都把作业给交了 xff0c 并且现在大多数UML课程都会让学生使用Rational Rose做画图练习 近来 xff0c 做毕业设计需要提供各种流
  • 浙大PTA平台上的题目题解

    记载一些题目的代码 xff0c 之后想要在b站讲题目 xff0c 到时候会把录的视频上传b站 不是大佬 xff0c 是蒟蒻 xff0c 大佬勿喷 xff0c 仅供参考 xff0c 欢迎大家star xff0c qwq 浙大版 C语言程序设计
  • git 入门教程

    想要将一个项目托管到github xff0c 需要进入项目所在文件夹进行git init命令初始化 Git提交代码的基本流程 xff1a 创建或修改 本地文件使用 git add 命令 xff0c 将创建或修改的文件添加到本地的暂存区 xf
  • 博客搬家

    谢谢大家对我的blog的支持 现在本科毕业 xff0c 准备读研 方向大概是机器学习这一块 又是一个新的开始 我想将我读研学习Python以及机器学习 深度学习 以及数据分析处理 大数据等学习教程放在新的blog上 xff1a blog 欢
  • Python多线程笔记(Python_MultiThread)

    4 MultiThreading 多线程 使用 xff1a a 什么是多线程 xff1f 简单明了 xff0c 让计算机在同一时间内同时运行多个程序 xff0c 并且每个程序的计算互不干扰 xff0c 我们称这样的操作为多线程运算 b ad
  • Python多进程笔记(Python_MultiProcess)

    1 MutiProcessing 多进程 使用 xff1a a 什么是多进程 xff1f 在上面我们使用多线程去分别处理不同的事情 xff0c 看起来 xff0c 多线程处理并不比单线程循环处理的效率看起来那么的高 多进程是在利用我们电脑C