首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

multiprocessing库:Python 并发并行的神器

multiprocessing是 Python 的一个标准库,它提供了一种基于进程的并行执行方式,可以有效地利用多核 CPU 的优势。虽然它被称为“基于进程的线程接口”,但实际上它使用的是进程而不是线程。这是因为 Python 的全局解释器锁 (GIL) 限制了多线程在 CPU 密集型任务中的性能提升。

「为什么需要multiprocessing?」

Python 的标准线程库threading由于 GIL 的存在,在 CPU 密集型任务中无法真正实现并行。GIL 保证了同一时刻只有一个线程在执行 Python 字节码。这意味着,即使在多核 CPU 上,Python 的多线程也只能利用一个 CPU 核心。

对于 I/O 密集型任务(例如网络请求、文件读写),多线程仍然有效,因为线程会在等待 I/O 操作完成时释放 GIL,允许其他线程执行。但对于 CPU 密集型任务(例如数值计算、图像处理),多进程才是更好的选择。

multiprocessing库通过创建独立的进程来绕过 GIL 的限制,每个进程都有自己独立的 Python 解释器和内存空间,因此可以真正实现并行执行,充分利用多核 CPU 的性能。

「multiprocessing的主要特点:」

「基于进程:」使用独立的进程而不是线程,绕过 GIL 的限制。

「类线程 API:」提供了类似于threading的 API,使得从多线程代码迁移到多进程代码相对容易。

「进程间通信:」提供了多种进程间通信 (IPC) 机制,例如管道 (Pipe)、队列 (Queue)、共享内存等。

「进程池:」提供了Pool类,可以方便地管理和调度多个进程。

「multiprocessing的主要组件:」

「Process类:」用于创建和管理进程。

「Pool类:」用于创建进程池,方便执行并行任务。

「Queue和Pipe:」用于进程间通信。

「Lock、RLock、Semaphore、Condition、Event:」用于进程间同步。

「Value和Array:」用于在进程间共享数据。

「基本用法:」

「使用Process类:」

import multiprocessing

import time

def worker(num):

  print(f"进程 {num} 正在工作")

  time.sleep(2)

  print(f"进程 {num} 完成工作")

if __name__ == "__main__":

  processes = []

  for i in range(5):

      p = multiprocessing.Process(target=worker, args=(i,))

      processes.append(p)

      p.start()

  for p in processes:

      p.join()

  print("所有进程完成")

在这个例子中,我们创建了 5 个进程,每个进程执行worker函数。p.start()启动进程,p.join()等待进程结束。

「使用Pool类:」

import multiprocessing

import time

def worker(num):

  print(f"进程 {num} 正在工作")

  time.sleep(2)

  return num * 2

if __name__ == "__main__":

  with multiprocessing.Pool(processes=3) as pool: # 创建一个拥有3个进程的进程池

      results = pool.map(worker, range(5)) # map函数将worker函数应用到range(5)的每个元素上,并返回结果列表

      print(results)

  print("所有进程完成")

Pool类可以更方便地管理多个进程,pool.map()方法可以将一个函数应用到一个可迭代对象的所有元素上,并返回结果列表。pool.apply_async()方法可以异步执行函数。

「进程间通信:」

import multiprocessing

def worker(q):

  q.put("来自子进程的消息")

if __name__ == "__main__":

  q = multiprocessing.Queue()

  p = multiprocessing.Process(target=worker, args=(q,))

  p.start()

  message = q.get()

  p.join()

  print(message)  # 输出:来自子进程的消息

这个例子使用Queue在父进程和子进程之间传递消息。

「注意事项:」

在 Windows 系统上,使用multiprocessing时,必须将主程序代码放在if __name__ == "__main__":块中。

进程的创建和销毁需要一定的开销,因此对于计算量很小的任务,使用多进程可能反而会降低性能。

进程间通信需要进行数据序列化和反序列化,也会带来一定的开销。

multiprocessing是 Python 中进行并行编程的重要工具,可以有效地利用多核 CPU 的优势,提高 CPU 密集型任务的执行效率。它提供了类似于threading的 API 和多种进程间通信机制,使得并行编程更加方便。在选择使用多线程还是多进程时,需要根据任务的类型进行选择。对于 I/O 密集型任务,多线程可能更合适;对于 CPU 密集型任务,多进程是更好的选择。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OT9qgW32wvIKGjw2zAOwkjXg0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券