python 包之 multiprocessing 多进程

Python 包之 multiprocessing 多进程

multiprocessing 是 Python 标准库中提供的模块,可以方便地使用多进程进行并发编程。它提供了与 Python 标准库 threading 模块相同的接口,但是使用多进程编程可以充分利用多核 CPU 的优势,用于加速 CPU 密集型任务。

multiprocessing 模块的主要组件

  • Process:进程对象,用于创建新进程。

  • Queue:进程间通信(IPC)的队列对象,用于在多个进程之间安全地共享数据。

  • Pool:进程池对象,用于管理池中的多个 Worker 进程,执行一组对数据集的并行操作。

  • LockRLockSemaphore:进程锁,用于控制多个进程对共享资源的访问。

创建新进程

multiprocessing.Process 可以用于创建新的进程,常用的方式有如下两种:

方式一:函数形式

import multiprocessing

def work(name):
    print(f"Working on {name}")

if __name__ == '__main__':
    p = multiprocessing.Process(target=work, args=('Alice',))
    p.start()
    p.join()

在上面的代码中,我们通过 multiprocessing.Process() 函数创建了一个新进程,并将 work() 函数作为任务传递给了该进程。start() 方法用于启动该进程,并且 join() 方法用于等待该进程完成。在运行该代码时,可以看到类似于如下输出:

Working on Alice

方式二:面向对象式

import multiprocessing

class Worker(multiprocessing.Process):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print(f"Working on {self.name}")

if __name__ == '__main__':
    p = Worker('Bob')
    p.start()
    p.join()

在上面的代码中,我们通过继承 multiprocessing.Process 类创建了一个新的进程对象,并覆盖了 run() 方法,该方法内部执行我们的工作。在运行该代码时,可以看到类似于如下输出:

Working on Bob

进程间通信

多个进程之间需要共享数据或结果时,可以使用 multiprocessing.Queue 类来实现进程间通信(IPC)。以下是一个示例,演示了两个进程之间如何实现数据的共享。

import multiprocessing

def producer(queue):
    for i in range(5):
        print(f'Producing {i}')
        queue.put(i)

def consumer(queue):
    while True:
        data = queue.get()
        if data is None:
            break
        print(f'Consuming {data}')

if __name__ == '__main__':
    queue = multiprocessing.Queue()
    p1 = multiprocessing.Process(target=producer, args=(queue,))
    p2 = multiprocessing.Process(target=consumer, args=(queue,))
    p1.start()
    p2.start()
    p1.join()
    queue.put(None)
    p2.join()

在上面的代码中,我们创建了一个 multiprocessing.Queue 对象,并将其传递给了两个进程函数进行共享。producer 进程函数用于生成数据并将其放入队列中,consumer 进程函数负责不断地取出队列中的数据并进行消费。

在执行该代码时,可以看到类似于如下输出:

Producing 0
Consuming 0
Producing 1
Consuming 1
Producing 2
Consuming 2
Producing 3
Consuming 3
Producing 4
Consuming 4

进程池

multiprocessing.Pool 类可以用于创建一个进程池,执行一组对数据集的并行操作。以下是一个示例,演示了如何使用 Pool 实现对列表中数字的并行求平方。

import multiprocessing

def square(x):
    return x*x

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    result = pool.map(square, [1, 2, 3, 4, 5])
    print(result)

在上面的代码中,我们创建了一个进程池,并使用 map() 方法实现对列表中数字的并行求平方。在运行该代码时,可以看到如下输出:

[1, 4, 9, 16, 25]

另外一个示例,演示了如何使用 Pool 实现对多个文件的并行读取和处理。

import multiprocessing
import os

def count_lines(filename):
    with open(filename, 'r') as f:
        lines = f.readlines()
    return len(lines)

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    folder_path = './files'
    filenames = [os.path.join(folder_path, f) for f in os.listdir(folder_path)]
    results = pool.map(count_lines, filenames)
    total_lines = sum(results)
    print(f'Total number of lines in {len(filenames)} files: {total_lines}')

在上面的代码中,我们创建了一个进程池,并使用 map() 方法实现对多个文件的并行读取和处理。其中,count_lines() 函数用于读取文件并返回其行数。在运行该代码时,需要先准备好指定路径下的多个文件,然后可以看到如下输出:

Total number of lines in 3 files: 15

进程锁

在多个进程共享同一份数据时,可能会出现多个进程同时读写该数据的情况,如果没有加锁保护,可能会导致数据的错误和不可预期的结果。可以使用 multiprocessing.Lockmultiprocessing.RLockmultiprocessing.Semaphore 等类来实现进程锁的功能。

以下是一个示例,演示了如何使用 Lock 类来保证多个进程安全地访问同一份数据。

import multiprocessing

def deposit(balance, lock):
    for i in range(10000):
        lock.acquire()
        balance.value += 1
        lock.release()

def withdraw(balance, lock):
    for i in range(10000):
        lock.acquire()
        balance.value -= 1
        lock.release()

if __name__ == '__main__':
    balance = multiprocessing.Value('i', 0)
    lock = multiprocessing.Lock()

    d = multiprocessing.Process(target=deposit, args=(balance, lock))
    w = multiprocessing.Process(target=withdraw, args=(balance, lock))

    d.start()
    w.start()
    d.join()
    w.join()

    print(balance.value)

在上面的代码中,我们创建了一个共享变量 balance,并分别创建了存款和取款两个进程,它们会在 10000 次循环中反复对 balance 进行加减操作。为了避免多个进程同时访问同一份数据,我们使用 multiprocessing.Lock 类来对访问 balance 的进程进行加锁保护。在运行该代码时,可以看到如下输出:

0

可以看到,经过了 20000 次加减操作,最终 balance 的值保持不变,证明了我们的加锁保护起了作用。

总结

在本篇文章中,我们介绍了 Python 标准库 multiprocessing 模块的主要组件,包括创建新进程、进程间通信、进程池、进程锁等。同时,我们也给出了多个示例,演示了如何使用 multiprocessing 进行并发编程的实际应用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 包之 multiprocessing 多进程 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 在Python中使用poplib模块收取邮件的教程

    当我们需要在Python中收取邮件时,可以使用poplib模块。这个模块提供了一组方法,可以连接和管理邮件服务器,并可以读取、下载和删除邮件。接下来我将介绍如何使用poplib模块收取邮件的攻略及两条示例。 步骤一:连接邮件服务器 首先,我们需要连接到邮件服务器。这可以通过以下代码实现: import poplib # 设置服务器地址、端口、用户名和密码 h…

    python 2023年5月20日
    00
  • win8下python3.4安装和环境配置图文教程

    在Windows 8操作系统下,我们可以使用以下步骤安装Python 3.4并配置环境。 1. 下载Python 3.4安装包 我们可以从Python官网下载Python 3.4的安装包。下载地址为:https://www.python.org/downloads/release/python-340/ 2. 安装Python 3.4 双击下载的Python…

    python 2023年5月15日
    00
  • python 层次聚类算法图文示例

    下面我将为您详细讲解“python 层次聚类算法图文示例”的完整攻略。 1.层次聚类算法 层次聚类算法是一种将相似数据点归为一类的无监督学习算法,它可以按照类似树这样的层次结构将数据点聚合成一个个簇。层次聚类算法的具体实现方式有两种:自下而上的聚合法和自上而下的分裂法。 在聚合法中,每个数据点最初都被看作一个簇,逐渐合并成大型簇,最终形成一个大的聚类树。而在…

    python 2023年6月5日
    00
  • Python 异常处理Ⅳ过程图解

    Python 异常处理过程图解 概述 异常处理是编写高可靠性程序的关键技能。当发生异常时,程序不会终止,而是跳转到相应的异常处理代码块。Python 中的异常处理包括 try、except、else 和 finally 四个关键字。错误类型需要与 Exception 类或其子类相匹配。 异常处理过程图解 异常处理流程如下: 程序运行,尝试执行 try 代码块…

    python 2023年5月13日
    00
  • Flask response响应的具体使用

    下面是关于Flask中响应的具体使用的完整攻略。 1. 使用Flask响应对象 当Flask应用需要返回响应时,可以使用Flask中自带的响应对象。常见的响应对象类型有: Response: 基础响应对象,可以设置状态码、响应头等。 make_response(): 使用Response对象创建响应。 jsonify(): 将字典或列表序列化成JSON格式的…

    python 2023年5月14日
    00
  • 浅谈python配置与使用OpenCV踩的一些坑

    浅谈Python配置与使用OpenCV踩的一些坑 简介 OpenCV是计算机视觉领域中应用最广泛的开源软件库之一,可用于图像处理、计算机视觉以及机器学习等方面。而Python作为一种功能强大的编程语言,也是使用OpenCV的最佳选择之一。 在使用Python和OpenCV进行图像处理的同时,也会遇到一些常见的问题和坑点。本篇文章将会详细讲解这些问题以及相应的…

    python 2023年5月13日
    00
  • Python自定义函数定义,参数,调用代码解析

    Python自定义函数定义、参数、调用代码解析 Python是一种高级编程语言,支持自定义函数。自定义函数是一种可重复使用的代码块,可以接受输入参数并返回输出结果。本文将详细讲解Python自定义函数的定义、参数、调用等相关知识,并提供两个示例。 自定义函数定义 在Python中,我们可以使用def关键字来定义自定义函数。以下是一个简单的自定义函数定义示例:…

    python 2023年5月15日
    00
  • Python计算IV值的示例讲解

    下面是关于“Python计算IV值的示例讲解”的完整攻略。 标题 什么是IV值 IV指隐私保护中常用的指标,即信息量。它既反应了数据的敏感程度,又反映了数据的稀缺性。通常情况下,IV值越大,预测目标变量的能力越高。 如何计算IV值 计算IV值的公式为:IV=∑(good%−bad%)×WOE,其中good表示好样本数,bad表示坏样本数,WOE表示分割后某一…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部