概述

在本文中,你将了解使用多进程,使用多重处理创建多进程,子进程等的利弊。

大多数CPU制造商现在都在制造多核CPU。 甚至手机也具有多个核心! 由于使用全局解释器锁定,Python线程无法使用这些内核。 从Python 2.6开始,添加了multiprocessing模块,该模块使你可以充分利用计算机上的所有内核。

在本文中,你将学习以下主题:

  • 使用多进程的优点
  • 使用多进程的缺点
  • 通过multiprocessing创建多进程
  • 子进程
  • 创建一个多进程池

本文不是multiprocessing的全面概述。 一般而言,多处理和并发这一主题将更适合于一本自己的书。 如果需要,你可以随时查看multiprocessing模块的文档:

https://docs.python.org/2/library/multiprocessing.html

现在,让我们开始吧!

使用多进程的优点

使用多进程有几个优点:

  • 多进程使用单独的内存空间
  • 与线程相比,代码可以更直接
  • 使用多个CPU /内核
  • 避免使用全局解释器锁定(GIL)
  • 子多进程可以被杀死(与线程不同)
  • multiprocessing模块具有类似于threading.Thread的接口。
  • 适用于CPU绑定处理(加密,二进制搜索,矩阵乘法)

现在,让我们看一下多进程的一些弊端!

使用多进程的缺点

使用多进程还有两个缺点:

  • 多进程间通信更加复杂
  • 内存占用大于线程

现在,让我们学习如何使用Python创建多进程!

通过multiprocessing创建多进程

multiprocessing模块旨在模仿threading.Thread类的工作方式。

下面是使用multiprocessing模块的示例:

import multiprocessing
import random
import time
def worker(name: str) -> None:
    print(f'Started worker {name}')
    worker_time = random.choice(range(1, 5))
    time.sleep(worker_time)
    print(f'{name} worker finished in {worker_time} seconds')
if __name__ == '__main__':
    processes = []
    for i in range(5):
        process = multiprocessing.Process(target=worker, 
                                          args=(f'computer_{i}',))
        processes.append(process)
        process.start()
    for proc in processes:
        proc.join()

第一步是导入multiprocessing模块。其他两个导入分别用于随机和时间模块。

然后,你就拥有了愚蠢的worker()函数,该函数假装要做一些工作。它接受一个名称,但不返回任何内容。在worker()函数内部,它将打印出工作程序的名称,然后将使用time.sleep()来模拟执行一些长时间运行的过程。最后,它将打印出已完成。

代码段的最后一部分是创建5个工作进程的位置。你使用multiprocessing.Process(),其工作方式与threading.Thread()几乎相同。你告诉Process使用什么目标函数以及要传递给什么参数。主要区别在于,这一次你要创建进程列表。对于每个进程,调用其start()方法以启动该进程。

最后,你遍历进程列表并调用其join()方法,该方法告诉Python等待进程终止。

运行此代码时,你将看到类似于以下内容的输出:

Started worker computer_2
computer_2 worker finished in 2 seconds
Started worker computer_1
computer_1 worker finished in 3 seconds
Started worker computer_3
computer_3 worker finished in 3 seconds
Started worker computer_0
computer_0 worker finished in 4 seconds
Started worker computer_4
computer_4 worker finished in 4 seconds

每次运行脚本时,由于使用随机模块,输出都会有所不同。 试试看!

子进程

multiprocessing模块中的Process类也可以被子类化。 它的工作方式与threading.Thread类的工作方式大致相同。


# worker_thread_subclass.py
import random
import multiprocessing
import time
class WorkerProcess(multiprocessing.Process):
    def __init__(self, name):
        multiprocessing.Process.__init__(self)
        self.name = name
    def run(self):
        """
        Run the thread
        """
        worker(self.name)
def worker(name: str) -> None:
    print(f'Started worker {name}')
    worker_time = random.choice(range(1, 5))
    time.sleep(worker_time)
    print(f'{name} worker finished in {worker_time} seconds')
if __name__ == '__main__':
    processes = []
    for i in range(5):
        process = WorkerProcess(name=f'computer_{i}')
        processes.append(process)
        process.start()
    for process in processes:
        process.join()

在这里,你可以对multiprocess.Process()进行子类化,并覆盖其run()方法。

接下来,在代码末尾的循环中创建流程,并将其添加到流程列表中。 然后,要使进程正常运行,你需要遍历进程列表,并在每个进程上调用join()。 这与上一节中的上一个流程示例完全一样。

此类的输出也应该与上一节的输出非常相似。

创建进程池

如果你有很多要运行的进程,有时你将希望限制可以一次运行的进程数。

例如,假设你需要运行20个进程,但是你的处理器只有4个内核。 你可以使用multiprocess模块创建一个进程池,该池将一次运行的进程数限制为仅4个。

方法如下:

import random
import time
from multiprocessing import Pool
def worker(name: str) -> None:
    print(f'Started worker {name}')
    worker_time = random.choice(range(1, 5))
    time.sleep(worker_time)
    print(f'{name} worker finished in {worker_time} seconds')
if __name__ == '__main__':
    process_names = [f'computer_{i}' for i in range(15)]
    pool = Pool(processes=5)
    pool.map(worker, process_names)
    pool.terminate()

在此示例中,你具有相同的worker()函数。 代码的实质是在最后使用列表推导创建15个进程名称。 然后,创建一个池并将一次要运行的进程总数设置为5。要使用该池,你需要调用map()方法,并将要调用的函数以及要传递给参数的参数传递给该方法。 功能。

在所有进程完成之前,Python现在将一次运行5个(或更少)进程。 你需要在池的最后调用terminate(),否则将看到类似以下的消息:

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/multiprocessing/resource_tracker.py:216:
UserWarning: resource_tracker: There appear to be 6 leaked semaphore objects to clean up at shutdown

现在你知道了如何使用Python创建进程池!

总结

你现在已经了解了使用多multiprocess的基础知识。 你已了解以下内容:

  • 使用多进程的优点
  • 使用多进程的缺点
  • 通过multiprocess创建多进程
  • 子进程
  • 创建进程池

multiprocess的功能远不止此处介绍。

你可以学习如何使用Python的Queue模块从流程中获取输出。 有进程间通信的主题。 而且还有更多。 但是,目标是学习如何创建多进程,而不是学习multiprocess模块的每一个细微差别。

并发是一个很大的话题,需要比本文涵盖的内容更深入的讨论。

SO资源郑重声明:
1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!3187589@qq.com
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理,有奖励!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!

SO资源 » Python创建多进程