Python教程:多进程与进程池的用法

Python中多进程和进程池的使用方法 本篇博客介绍了Python中多进程和进程池的使用方法,并提供了一些实用的案例供读者参考。多进程和进程池是Python中强大的功能之一,可以帮助我们更加高效地利用CPU资源,提高程序的运行速度。在实际应用中,需要根据具体情况选择合适的方案来实现多进程和进程池。 阅读详情

一、进程:

一个程序运行起来后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单元。其也会有并发与并行的状态,与多线程不同的是,多进程会充分利用CPU的资源来执行任务。

进程的状态:
当任务数大于CPU的核数时,部分任务在执行,部分任务在等待执行,因此就会产生不通的状态:
1.就绪状态:运行条件以满足,等待CPU执行。
2.执行状态:CPU正在执行其任务。
3.等待状态:等待某些条件满足,例如一个程序sleep了。

multiprocessing模块
python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,其支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件

Process:
使用方法与线程Thread类一样如下,需要注意的是进程的创建与启动必须放在__main__下面,否则会造成循环加载任务代码的问题。

from multiprocessing import Process

a = 0

def work(name):
    global a
    for i in range(100):
        a += 1
    print(f"{name}----", a)


def work1(name):
    global a
    for i in range(100):
        a += 1
    print(f"{name}----", a)


if __name__ == '__main__':
    p = Process(target=work, args=('MING',)) # 创建进程对象,通过args传入任务参数
    p1 = Process(target=work1,args=('CHAZ',),daemon=True) #设置进程是否为守护进程,如果是守护进程,则与主进程一起关闭。
    p.start() # 启动进程
    p1.start()
    p.join() # 等待进程执行完成
    p1.join()
    print('a:', a)

>>>MING---- 100
>>>CHAZ---- 100
>>>a: 0

os.getpid()查看进程id,os.getppid(),查看父进程id

import time,os
from multiprocessing import Process


def fun():
    time.sleep(2)
    print(f"fun--进程id{os.getpid()},父进程id{os.getppid()}")


def fun1():
    time.sleep(2)
    print(f"fun1--进程id{os.getpid()},父进程id{os.getppid()}")


if __name__ == '__main__':
    p = Process(target=fun)
    p1 = Process(target=fun1)
    p.start()
    p1.start()
    p.join()
    p1.join()
    print(f'主进程--{os.getpid()}')
 
>>> fun--进程id18188,父进程id14604
>>> fun1--进程id19256,父进程id14604
>>> 主进程--14604

从例1中可以看到进程之间的信息是独立的,并没有共享,如果想实现进程之间的通信可以使用Queue模块,(需要注意的是并非queue模块中的Queue,此队列只能用来在一个进程中的多个线程之间使用)。而进程中的Queue可以在多个进程之间跨进程传输数据。
导入:

from multiprocessing import Queue

举例:
一个列表中有10个url地址,每个地址请求一次,使用2个进程程去发送这 10个请求(假设请求每个地址需要0.5秒)
在不使用Queue的情况下:

from multiprocessing import Process
import time

li = ['www.baidu.com-{}'.format(i) for i in range(10)]


def work():
    while li:
        url = li.pop()
        print("请求地址:", url)
        time.sleep(0.5)


if __name__ == '__main__':
    t = Process(target=work)
    t1 = Process(target=work)
    t.start()
    t1.start()
    t.join()
    t1.join()

运行结果:

请求地址: www.baidu.com-9
请求地址: www.baidu.com-9
请求地址: www.baidu.com-8
请求地址: www.baidu.com-8
请求地址: www.baidu.com-7
请求地址: www.baidu.com-7
请求地址: www.baidu.com-6
.....

此时每个进程拿到的列表是独立的,并不是共享的才造成上面的问题。如下,使用进程中的队列解决这一问题:

from multiprocessing import Process, Queue
import time

def work(urls):
    while not urls.empty(): # 判断队列是否为空
        url = urls.get() # 获取队列中的值
        print("请求地址:", url)
        time.sleep(0.5)


if __name__ == '__main__':
    urls = Queue() # 创建队列
    for i in range(10):
        urls.put(f"www.baidu.com-{i}") # 队列中添加数据
    t = Process(target=work, args=(urls,)) # 创建进程对象,将队列作为函数的参数
    t1 = Process(target=work, args=(urls,))
    t.start()
    t1.start()
    t.join()
    t1.join()

运行结果:

请求地址: www.baidu.com-0
请求地址: www.baidu.com-1
请求地址: www.baidu.com-2
请求地址: www.baidu.com-3
请求地址: www.baidu.com-4
请求地址: www.baidu.com-5
....

二、进程池

当需要创建的子进程数量不多时,可以直接使用Process动态生成多个进程,但如果是上百个甚至更多的目标,通过手动创建进程的工作量巨大,此时可以用到multiprocessing模块提供的Pool方法。

创建进程池时候可以指定最大进程数,当有新的请求要提交到Pool中时,会判断Pool中有没有达到最大进程数,如果达到,该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务。
进程池之间的通讯使用Manager中的Queue()。

from multiprocessing import Pool
import time

def func(msg):
    print("msg:", msg)
    time.sleep(3)

if __name__ == "__main__":
    po = Pool(3) # 创建进程池
    for i in range(4):
        msg = f"hello{i}"
        po.apply_async(func, (msg,))  # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去

    print("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~")
    po.close()
    po.join()  # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
    print("Sub-process(es) done.")

ProcessPoolExecutor:与线程池ThreadPoolExecutor 原理及使用方法是一样的,通过ProcessPoolExecutor创建线程池,submit提交任务到线程池。max_workers指定线程池中的数量

import time
from concurrent.futures import ProcessPoolExecutor


def work(name):
    for i in range(5):
        time.sleep(1)
        print(f"{name}----{i}----")

#学习中遇到问题没人解答?小编创建了一个Python学习交流群:711312441
with ProcessPoolExecutor(max_workers=4) as tp: # 创建进程池
    tp.submit(work, 'MING') # 往进程提交任务
    tp.submit(work, 'HOUX')
	tp.shutdown() # 等待进程池中所有的任务执行完成
    print("---主进程---")

运行结果:

MING----0----HOUX----0----

MING----1----HOUX----1----

HOUX----2----MING----2----

MING----3----HOUX----3----

HOUX----4----MING----4----

---主进程---
Python实现多进程:Pool类详解 文章目录1 引言2 Pool类2.1 Pool类中的方法列表2.1.1 五种分派任务的方法2.1.2 三种管理进程池的方法:2.2 apply(func[, args[, kwds]])方法2.3 apply_async(func[, args[, kwds[, callback[, error_callback]]]])方法2.4 `map(func, iterable[, chunksize]... 阅读详情

相关推荐

116、Python并发编程:使用进程池实现多进程编程的两种方法

本文首先介绍了使用进程池的优势,以及其适用的业务场景。然后,分别介绍了基于multiprocessing.Pool和concurrent.futures.ProcessPoolExecutor的进程池的创建和使用。最后,简单比较了两种实现方式。

南宫理的日知录 817

Python 多进程&多线程&线程池&进程池&协程

Python 多进程&多线程&线程池&进程池&协程

喵酱 3876

python中多进程及multiprocessing进程池使用——批量读取excel文件

首先准备:当前文件上级目录下有个excels目录,目录里存在15份.xls文件,每个文件1000条数据,需要通过多进程对这些文件读取为pandas的dataframe格式 手动创建多进程读取文件(进程数等于任务数) # @datetime:6/26/0026 """通过多进程加速读取excel的测试""" __author__ = "hanyaning@deri.energy" import os...

hynkoala的博客 4793

(python)多进程

工作中遇到任务较重且耗时相对较长的情况,这时候想起来用多进程处理这类IO 密集型任务.最重要的是,multiprocessing.Pool实在是简单又高效,充分利用了多核CPU同时并行处理多个任务.支持多进程并行处理,可以利用多核 CPU 提高任务的执行效率和速度。提供了简单易用的 API,方便进行任务的分发和结果的收集,代码编写相对简单。可以在一定程度上降低代码复杂度,例如避免手动创建和管理多个进程等。缺点:进程切换开销较大,特别是当进程池中进程数量过多时,容易产生性能瓶颈。

MARST.ZHANG的博客 4395

python多进程cpu的占用率很低_Python 中的进程池与多进程

封面图片来源:沙沙野内容概览进程池进程池和多进程的性能测试进程池的其他机制进程池的回调函数进程池如果有多少个任务,就开启多少个进程,实际上并不划算。由于计算机的 cpu 个数是非常有限的因此开启的进程数量完全和 cpu 个数成比例进程池的特点:同一时间最多有多少个进程能够同时执行任务与进程池中进程的个数有关系如果进程池设置了个数,那么程序只会开启四个进程运行from multiprocessing...

weixin_39658759的博客 2421

并行-为什么你的多进程池卡住了

Python 提供了一个方便的模块,允许你在进程池中运行任务,这是提高程序并行性的好方法。(注意,这些示例没有在 Windows 上测试;我在这里专注于 *nix 平台。如你所见,double()函数在不同的进程中运行。

liluo0815481的博客 1374

python:多进程池嵌套以及内存管理

前言 在使用进程嵌套进行并行调参的过程中,使用了close关闭进程池,使得创建的进程池中的进程变为stopped状态,造成了内存泄漏,最后导致了内存溢出,最后发现了问题整理了这篇文章。 1.进程池 当创建的子进程数量不多时,可以使用multiprocessing.Process动态创建。但是,当创建的子进程数量很多时,因为创建子进程也需要开销,如果按照上述方面创建,代价较高,因此使用进程池进行创建...

yyliunianyy的专栏 6955

Python多进程——进程池的开启和多进程操作同一个List

目标网站数据量多,想赶时间多获取点东西? 数据库大批量的数据需要操作? 单纯的想要节省时间,早早下班? ............ 肯定会有人说【多线程】。Python的多线程为了数据安全设置了GIL全局解释器锁,而Python的多线程是靠并发的方式实现的,即Python只会在一个进程里永远执行一个线程。 这就导致Python多线程的多线程效率低下。举个例子,这就相当于一个人在左右横跳的吃两包薯片。只不过这个人啊,他速度很快,只要左右横跳的速度足够快,他的残影就像两个人...

CorGi_8456的博客 3993

Python中的多进程与进程池

Python中的多进程与进程池 文章目录Python中的多进程与进程池1.multiprocessing类2.multiprocessing.Pool进程池构造方法常用方法多进程,多线程的选择应用Linux的特殊进程僵尸进程孤儿进程守护进程 1.multiprocessing类 方法 含义 current_process() 获取当前进程对象类似于threading.current...

兰枫 2279

python系列【仅供参考】:Python 多进程 multiprocessing.Pool类详解

Python 多进程 multiprocessing.Pool类详解

weixin_54626591的博客 413

python3爬虫系列17之爬虫增速多进程,进程池的用法(白话解释)

python3爬虫系列16之爬虫增速多进程,进程池的用法(白话解释) 1.前言 上一篇文章呢, python3爬虫系列15之多线程爬取汽车之家批量下载图片,我们采用了多线程的方式来爬取, 在耗时环节呢,感觉并不是很快,才600多张图片花了近21秒。 至于原因呢,也在最后告诉了大家, 多线程下的 GIL 锁让python的多线程显得有点鸡肋, GIL锁 即全局排他锁,保护了数据安全性的同时,使得多...

空空说技术的博客 4771

Python线程池、进程池的介绍与使用

 最近在做的一个项目是用python同时给多个用户提供科学计算。为了最大化并行服务的用户数量,需要用到多进程;为了最大化多个用户使用的公平性,需要用到多线程。

m0_50596083的博客 5245

PCB工程师必看:别再搞错1078玻纤布的Dk了,手把手教你算等效介电常数

本文为PCB工程师提供了1078玻纤布等效介电常数(Dk)的详细计算指南,帮助解决高速设计中的信号完整性问题。通过解析玻纤布结构、混合介质理论和实战计算方法,指导工程师准确设置EDA工具参数,避免常见的Dk计算误区,提升设计精度和仿真准确性。

weixin_42546392的博客 399

python3.8 进程池 多进程的实现 加速程序运行

进程池 我们使用multiprocessing库下的Pool开启多进程 multiprocessing是python3内置的,不需要下载安装,直接导入即可 我们写个简单的实例,来展示到底为什么要使用多进程,以及多进程有哪些作用 让我们使用进程的第一种情况观察 阻塞 from time import sleep from multiprocessing import Pool import os # 引入os库的作用是为了获取子进程的ID,让我们更直观查看进程的进度 def pid():

USADA 4807

运算放大器 VS 仪表放大器

运算放大器(Operational Amplifier, 简称 Op Amp)和仪表放大器(Instrumentation Amplifier, 简称INA)在电子电路设计中都有非常广泛的应用,但两者在结构、特性以及应用场景上都有明显的区别。以下是它们之间主要的差异:运算放大器(Op Amp)仪表放大器(INA)运算放大器仪表放大器运算放大器仪表放大器运算放大器仪表放大器运算放大器仪表放大器总之,运算放大器是通用型放大元件,需要设计者自己做额外的电路配置;而仪表放大器则是针对高精度测量差分信号而生,内部匹配

chinahongjiang的博客 1349

Simplorer-Maxwell联合仿真速度太慢?我用这3个技巧把仿真时间砍半(附SVPWM周期与步长设置避坑)

本文详细介绍了Simplorer-Maxwell联合仿真性能优化的3个关键技巧,包括仿真步长与周期的科学配置、基于任务调度的加速技术以及模型简化与精度平衡。特别针对SVPWM参数设置提供了避坑指南,帮助工程师在不牺牲精度的情况下将仿真时间缩短50%以上,适用于电机驱动系统开发等场景。

weixin_29189381的博客 466

python—多进程之进程池

一、进程池 1、进程池定义: 进程池:可以提供指定数量的进程给用户使用,即当有新的请求提交到进程池中时,如果池未满,则会创建一个新的进程用来执行该请求;反之,如果池中的进程数已经达到规定最大值,那么该请求就会等待,只要池中有进程空闲下来,该请求就能得到执行。 2、原理图 绿色:子进程没有工作,处于空闲状态(子进程没有调用任务函数) 粉色:子进程处于工作状态(子进程调用了任务函数) 3、使用进程池的优点 1.提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间 2.节省内存空间 4、Pool中的函数

python全栈 6404

Frida动态Hook实战:逆向美团外卖mtgsig3.0签名算法

在移动应用安全与数据爬取领域,API签名是保障请求合法性与数据完整性的核心机制。其原理是通过特定算法,将请求参数、时间戳等动态要素加密生成唯一字符串,服务器端通过验签防止数据篡改与伪造。这项技术的核心价值在于,它构建了客户端与服务器之间的可信通道,是移动端数据交互安全的基础。在自动化测试、安全审计、市场数据分析等应用场景中,理解并能够获取或绕过签名验证是关键前提。本文聚焦于美团外卖App的核心签名参数mtgsig3.0,针对其复杂的算法逻辑,提供了一套基于Frida的动态Hook解决方案。通过Hook技术,

weixin_33935636的博客 835

Python 多进程池的学习

最近想用python写个爬虫,根据学校图书馆的学号密码。由于学校图书馆初始密码为6位数字,而且不需要验证码,所以破解起来很简单。思路就是生成6为数字暴力密码本,依次向网页POST“学号-密码”的表单即可。然后问题来了,6位数字组成的密码,也就是0-9的六位全排列,共1000000中排列。 短短40行的单进程代码,需要56个小时才能把1000000个暴力密码轮询完毕。可怕。。。。   以前学习的时候

工作赚钱去旅行 2710

NRF24L01学习操作教程(二)——NRF实现一对一,一对多通讯

以上内容详细介绍了,使用NRF24L01实现1对1单向通讯、1对1双向通讯、1对多双向通讯。

Joseph Wen的博客 7391

MIKE水动力笔记2_水动力基础理论知识

本文所讲内容是水动力基础理论知识,所参考的主要书籍是《水动力学和水质》(第二版,季振刚著,海洋出版社)。

晏长街的博客 1万+

Python多进程库multiprocessing中进程池Pool类的使用

multiprocessing模块提供process类实现新建进程,可以在Python中實現並行的效果。

小平子的专栏 6万+

蓝桥杯 stm32 PWM 测量频率

参考 数据手册:比赛 的板子 上面有两个信号发生器,如下图。通过 扭动 可变电阻 (R40, R39), 来实现 PWM 频率的改变。PA15PB4。PA15,PB4分别使用TIM2_CH1TIM3_CH1来对频率进行捕获。

wuyiyu_的博客 2931

python系列——多进程之进程池(pool)

1、如何创建一个进程池 https://www.cnblogs.com/aylin/p/5601969.html Pool类描述了一个工作进程池,他有几种不同的方法让任务卸载工作进程。 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。 我们可以用Pool类创建一个进程池, 展开提交的任务给进程池。 例: #apply (非阻塞,异步方式) from multiprocessing import

有信念,才能走的更远 1万+

【全覆盖算法】Boustrophedon Cellular Decomposition(BCD)原理及实现

本文先对做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。

qq_35635374的博客 504

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Python 多进程 进程池

Python 多进程 进程池 在前文Python 多进程编程介绍了Python的多进程库multiprocessing中的进程池类Pool,但是后来使用的时候还是发现一些不好用的地方。这里我自己做了一个自定义的进程池 MultiProcessPool类来方便处理。 系统的进程池类 Pool 如下代码,所有的子进程返回结果都是保存在一个名为tasks的list中。 处理子进程返回结果的时...

xuelians的博客 2444

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: python中parse的action = store_true含义
下一篇: python使用selenium操作浏览器的教程
Python热爱者
博客等级 码龄7年 3059粉丝 1330原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值