Python中的多进程通信实践指南

简介: Python中的多进程通信实践指南

并发编程领域,多进程是一种常见的模式,它可以充分利用多核处理器的计算能力。然而,进程间的通信(Inter-Process Communication,IPC)是多进程编程中的一个核心议题。Python标准库中的multiprocessing模块提供了多种方式来实现进程间的通信。我将深入探讨如何使用Python中的multiprocessing模块实现进程间通信。

使用队列(Queue)进行进程间通信

队列是一种基于先进先出(FIFO)原则的数据结构,非常适合用于进程间的消息传递。multiprocessing模块提供了一个同名的Queue类,可以被多个进程共享。

以下是一个简单的例子,演示了如何使用multiprocessing.Queue来在两个进程间传递消息:

from multiprocessing import Process, Queue
def producer(queue):
    # 生产者进程,将数据放入队列
    for i in range(5):
        queue.put(f"数据 {i}")
        print(f"数据 {i} 已发送。")
def consumer(queue):
    # 消费者进程,从队列中获取数据
    while True:
        data = queue.get()
        if data is None:
            break  # 如果收到None,代表发送完毕
        print(f"数据 {data} 已接收。")
if __name__ == "__main__":
    # 创建一个共享队列
    queue = Queue()
    # 创建生产者和消费者进程
    prod = Process(target=producer, args=(queue,))
    cons = Process(target=consumer, args=(queue,))
    # 启动进程
    prod.start()
    cons.start()
    # 等待生产者结束
    prod.join()
    # 发送结束信号
    queue.put(None)
    # 等待消费者结束
    cons.join()

在上述代码中:

  • 第1-2行:导入了必要的类。
  • 第4-9行:定义了一个名为producer的函数,它是生产者进程的入口点,用于向队列发送数据。
  • 第11-18行:定义了一个名为consumer的函数,它是消费者进程的入口点,用于从队列接收数据。
  • 第20-31行:在__main__保护块中创建队列和进程,并启动它们。这是必要的,以防止子进程无限递归地创建新进程。

使用管道(Pipe)进行进程间通信

管道是另一种常见的IPC机制。在multiprocessing模块中,Pipe()函数返回一对连接对象,分别代表管道的两端。每一端都有send()recv()方法,用于发送和接收消息。

下面的例子展示了如何使用multiprocessing.Pipe进行通信:

from multiprocessing import Process, Pipe
def sender(pipe):
    # 发送端进程,发送数据
    for i in range(5):
        pipe.send(f"数据 {i}")
        print(f"数据 {i} 已发送。")
def receiver(pipe):
    # 接收端进程,接收数据
    for i in range(5):
        data = pipe.recv()
        print(f"数据 {data} 已接收。")
if __name__ == "__main__":
    # 创建管道
    parent_conn, child_conn = Pipe()
    # 创建发送和接收进程
    sender_proc = Process(target=sender, args=(parent_conn,))
    receiver_proc = Process(target=receiver, args=(child_conn,))
    # 启动进程
    sender_proc.start()
    receiver_proc.start()
    # 等待进程结束
    sender_proc.join()
    receiver_proc.join()

在这段代码中:

  • 第1-2行:导入了必要的类。
  • 第4-9行:定义了一个名为sender的函数,它是发送端进程的入口点。
  • 第11-16行:定义了一个名为receiver的函数,它是接收端进程的入口点。
  • 第18-28行:在__main__保护块中创建了管道的两端、进程,并启动它们。

使用共享内存(Value, Array)进行进程间通信

multiprocessing提供了ValueArray类,允许创建可以被多个进程共享的数据。这些数据存储在共享内存中,进程可以直接读写。

下面是一个使用共享内存的例子:

from multiprocessing import Process, Value, Array
def add_one(number, array):
    # 对共享数据进行操作
    number.value += 1
    for i in range(len(array)):
        array[i] += 1
if __name__ == "__main__":
    # 创建共享数据
    shared_number = Value('i', 0)
    shared_array = Array('d', [0.0, 100.0, 200.0])
    # 创建并启动进程
    process_list = []
    for _ in range(10):
        p = Process(target=add_one, args=(shared_number, shared_array))
        process_list.append(p)
        p.start()
    # 等待所有进程完成
    for p in process_list:
        p.join()
    # 打印共享数据的结果
    print(f"共享数字: {shared_number.value}")
    print(f"共享数组: {list(shared_array)}")

在这个例子中:

  • 第1-2行:导入了必要的类。
  • 第4-8行:定义了一个名为add_one的函数,它接收共享的数字和数组,并对它们的每个元素加一。
  • 第10-23行:在__main__保护块中创建共享数据、进程,并启动这些进程。

Python的multiprocessing模块,通过队列、管道和共享内存等机制实现了进程间通信的几种方法。这些机制在解决并发编程中的数据交换问题时非常有用



目录
相关文章
|
2月前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
2月前
|
存储 Unix Linux
进程间通信方式-----管道通信
【10月更文挑战第29天】管道通信是一种重要的进程间通信机制,它为进程间的数据传输和同步提供了一种简单有效的方法。通过合理地使用管道通信,可以实现不同进程之间的协作,提高系统的整体性能和效率。
|
2月前
|
消息中间件 存储 供应链
进程间通信方式-----消息队列通信
【10月更文挑战第29天】消息队列通信是一种强大而灵活的进程间通信机制,它通过异步通信、解耦和缓冲等特性,为分布式系统和多进程应用提供了高效的通信方式。在实际应用中,需要根据具体的需求和场景,合理地选择和使用消息队列,以充分发挥其优势,同时注意其可能带来的复杂性和性能开销等问题。
|
2月前
|
调度 iOS开发 MacOS
python多进程一文够了!!!
本文介绍了高效编程中的多任务原理及其在Python中的实现。主要内容包括多任务的概念、单核和多核CPU的多任务实现、并发与并行的区别、多任务的实现方式(多进程、多线程、协程等)。详细讲解了进程的概念、使用方法、全局变量在多个子进程中的共享问题、启动大量子进程的方法、进程间通信(队列、字典、列表共享)、生产者消费者模型的实现,以及一个实际案例——抓取斗图网站的图片。通过这些内容,读者可以深入理解多任务编程的原理和实践技巧。
105 1
|
2月前
|
JSON 测试技术 持续交付
自动化测试与脚本编写:Python实践指南
自动化测试与脚本编写:Python实践指南
46 1
|
3月前
|
Python
Python中的多线程与多进程
本文将探讨Python中多线程和多进程的基本概念、使用场景以及实现方式。通过对比分析,我们将了解何时使用多线程或多进程更为合适,并提供一些实用的代码示例来帮助读者更好地理解这两种并发编程技术。
|
2月前
|
监控 JavaScript 前端开发
python中的线程和进程(一文带你了解)
欢迎来到瑞雨溪的博客,这里是一位热爱JavaScript和Vue的大一学生分享技术心得的地方。如果你从我的文章中有所收获,欢迎关注我,我将持续更新更多优质内容,你的支持是我前进的动力!🎉🎉🎉
29 0
|
6月前
|
运维 关系型数据库 MySQL
掌握taskset:优化你的Linux进程,提升系统性能
在多核处理器成为现代计算标准的今天,运维人员和性能调优人员面临着如何有效利用这些处理能力的挑战。优化进程运行的位置不仅可以提高性能,还能更好地管理和分配系统资源。 其中,taskset命令是一个强大的工具,它允许管理员将进程绑定到特定的CPU核心,减少上下文切换的开销,从而提升整体效率。
掌握taskset:优化你的Linux进程,提升系统性能
|
6月前
|
弹性计算 Linux 区块链
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
199 4
Linux系统CPU异常占用(minerd 、tplink等挖矿进程)
|
5月前
|
算法 Linux 调度
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。