python多进程multiprocessing使用

简介: 如果你想在python中使用线程来实现并发以提高效率,大多数情况下你得到的结果是比串行执行的效率还要慢;这主要是python中GIL(全局解释锁)的缘故,通常情况下线程比较适合高IO低CPU的任务,否则创建线程的耗时可能比串行的还要多。GIL是历史问题,和C解释器有关系。为了解决这个问题,python中提供了多进程的方式来处理需要并发的任务,可以有效的利用多核cpu达到并行的目的。【2月更文挑战第5天】

python多进程multiprocessing使用

1. 为什么需要multiprocessing

如果你想在python中使用线程来实现并发以提高效率,大多数情况下你得到的结果是比串行执行的效率还要慢;这主要是python中GIL(全局解释锁)的缘故,通常情况下线程比较适合高IO低CPU的任务,否则创建线程的耗时可能比串行的还要多。GIL是历史问题,和C解释器有关系。

为了解决这个问题,python中提供了多进程的方式来处理需要并发的任务,可以有效的利用多核cpu达到并行的目的。

但是需要注意的是,进程之间的资源是相互独立的,特别是内存;如果你需要在进程之间交换数据,共享信息,你需要有别于单进程的方式来创建你的代码。

好在multiprocessing包针对这些问题都提供了良好的解决方案。接下来就让我们一睹真容。

2. multiprocessing使用

2.1 Process

from multiprocessing import Process
import os

def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())
    print('process id:', os.getpid())

def f(name):
    info('function f')
    print('hello', name)


info('main line')
p_list = []
for i in range(5):
    p = Process(target=f, args=('the {}-th bob'.format(i),))
    p_list.append(p)
    p.start()

for i in range(5):
    p_list.get(i).join

2.2 进程池Pool

进程占用的是系统的资源,一般不会创建很多,否则资源不足的进程还是要等待获取资源。比如1000个任务,不会移动1000个进程,一是进程启动需要耗时,一是进程之间抢占资源。multiprocessing提供了进程池的方式,共享进程的使用。

from multiprocessing import Pool
import time

def add_by_input(i):
    time.sleep(2)
    return i+100

def end_call(arg):
    print("end_call",arg)

p = Pool(5)
for i in range(10):
    p.apply_async(func=add_by_input, args=(i,), callback=end_call)

print("end")
p.close()
p.join()

3. multiprocessing通信

multiprocess.Queue是跨进程通信队列。但是不能用于multiprocessing.Pool多进程的通信。

multiprocessing.Manager
进程池multiprocessing.Pool()的多进程之间的通信要用multiprocessing.Manager().Queue()

一个multiprocessing.Manager对象会控制一个服务器进程,其他进程可以通过代理的方式来访问这个服务器进程。从而达到多进程间数据通信且安全。

Manager支持的类型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array。

3.1 进程间同步锁

进程之间如果存在资源互斥的情况,可以通过Lock进行加锁。acquire获得独占锁,release释放锁。

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    try:
        print('hello world', i)
    finally:
        l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f, args=(lock, num)).start()

3.2 共享数据

多进程之间最好避免数据共享,进程之间要共享数据可以通过Manager来启动一个服务进程,来协调进程之间数据的共享。

Manager() 返回的管理器支持类型: list 、 dict 、 Namespace 、 Lock 、 RLock 、 Semaphore 、 BoundedSemaphore 、 Condition 、 Event 、 Barrier 、 Queue 、 Value 和 Array

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p = Process(target=f, args=(d, l))
        p.start()
        p.join()

        print(d)
        print(l)
# {0.25: None, 1: '1', '2': 2}
# [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

4. 总结

本文分享了multiprocessing来进行python多进程操作,希望对你有帮助。总结如下:

  • 利用好multiprocessing好Pool,共享资源池
  • 进程间共享锁用Lock
  • 进程间数据共享,通过Manager做中间进程服务,速度慢点
目录
相关文章
|
17天前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
29天前
|
调度 iOS开发 MacOS
python多进程一文够了!!!
本文介绍了高效编程中的多任务原理及其在Python中的实现。主要内容包括多任务的概念、单核和多核CPU的多任务实现、并发与并行的区别、多任务的实现方式(多进程、多线程、协程等)。详细讲解了进程的概念、使用方法、全局变量在多个子进程中的共享问题、启动大量子进程的方法、进程间通信(队列、字典、列表共享)、生产者消费者模型的实现,以及一个实际案例——抓取斗图网站的图片。通过这些内容,读者可以深入理解多任务编程的原理和实践技巧。
53 1
|
2月前
|
Python
Python中的多线程与多进程
本文将探讨Python中多线程和多进程的基本概念、使用场景以及实现方式。通过对比分析,我们将了解何时使用多线程或多进程更为合适,并提供一些实用的代码示例来帮助读者更好地理解这两种并发编程技术。
|
2月前
|
数据挖掘 程序员 调度
探索Python的并发编程:线程与进程的实战应用
【10月更文挑战第4天】 本文深入探讨了Python中实现并发编程的两种主要方式——线程和进程,通过对比分析它们的特点、适用场景以及在实际编程中的应用,为读者提供清晰的指导。同时,文章还介绍了一些高级并发模型如协程,并给出了性能优化的建议。
31 3
|
2月前
|
存储 Python
Python中的多进程通信实践指南
Python中的多进程通信实践指南
24 0
|
2月前
|
数据采集 消息中间件 Python
Python爬虫-进程间通信
Python爬虫-进程间通信
|
3月前
|
数据采集 Linux 调度
Python之多线程与多进程
Python之多线程与多进程
|
3月前
|
存储 算法 Java
关于python3的一些理解(装饰器、垃圾回收、进程线程协程、全局解释器锁等)
该文章深入探讨了Python3中的多个重要概念,包括装饰器的工作原理、垃圾回收机制、进程与线程的区别及全局解释器锁(GIL)的影响等,并提供了详细的解释与示例代码。
31 0
|
4月前
|
数据采集 并行计算 安全
Python并发编程:多进程(multiprocessing模块)
在处理CPU密集型任务时,Python的全局解释器锁(GIL)可能会成为瓶颈。为了充分利用多核CPU的性能,可以使用Python的multiprocessing模块来实现多进程编程。与多线程不同,多进程可以绕过GIL,使得每个进程在自己的独立内存空间中运行,从而实现真正的并行计算。
|
4月前
|
Unix Linux API
Python multiprocessing模块
Python multiprocessing模块