Python精选200Tips:106-110

100里python学习之路,现已走过90里,一半了

运行系统:macOS Sonoma 14.6.1
Python编译器:PyCharm 2024.1.4 (Community Edition)
Python版本:3.12

往期链接:

1-5 6-10 11-20 21-30 31-40 41-50
51-60:函数 61-70:类 71-80:编程范式及设计模式
81-90:Python编码规范 91-100:Python自带常用模块-1
101-105:Python自带模块-2

106 multiprocessing: 多进程支持

multiprocessing 模块是 Python 的一个内置模块,用于实现多进程并行处理。与 threading 模块不同,multiprocessing 模块可以充分利用多核 CPU 的优势,使得 CPU 密集型任务能够更高效地执行。主要功能:

  • 创建进程: 使用 Process 类可以创建新进程。
  • 进程间通信: 提供了多种方式(如队列、管道等)来实现进程间的数据交换。
  • 共享内存: 可以共享数据,使用 Value 和 Array。
  • 进程池: 使用 Pool 来管理多个进程,简化并行任务的管理。
  • 同步机制: 提供锁、信号量等工具来管理进程间的同步。
  1. 创建和启动进程
import multiprocessing
import time

def worker(name):
    print(f"Worker {
     name} starting")
    time.sleep(2)
    print(f"Worker {
     name} finished")

if __name__ == "__main__":
    processes = []
    for i in range(5):
        process = multiprocessing.Process(target=worker, args=(f"Process-{
     i}",))
        processes.append(process)
        process.start()

    # 等待所有进程完成
    for process in processes:
        process.join()

    print("All processes finished.")
  1. 进程间通信

使用队列 (Queue) 或管道 (Pipe) 实现进程间的消息传递。

import multiprocessing

def worker(queue):
    queue.put("Hello from worker!")

if __name__ == "__main__":
    queue = multiprocessing.Queue()
    process = multiprocessing.Process(target=worker, args=(queue,))
    process.start()
    message = queue.get()  # 从队列中获取消息
    process.join()
    print(f"Received message: {
     message}")
  1. 共享内存

使用共享内存对象(如 Value 和 Array)来在进程间共享数据。

import multiprocessing

def increment(shared_num):
    for _ in range(100):
        shared_num.value += 1

if __name__ == "__main__":
    shared_num = multiprocessing.Value('i', 0)  # 创建一个共享整数
    process = multiprocessing.Process(target=increment, args=(shared_num,))
    process.start()
    process.join()
    print(f"Final value: {
     shared_num.value}")
  1. 共享内存

使用 Pool 类来管理多个进程,简化并行任务的管理。

import multiprocessing
import time

def square(n):
    time.sleep(1)
    return n * n

if __name__ == "__main__":
    numbers = [1, 2, 3, 4, 5]

    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(square, numbers)

    print(f"Squares: {
     results}")
  1. 同步机制

使用锁 (Lock)、信号量 (Semaphore) 和条件变量 (Condition) 等机制来管理进程间的同步。

import multiprocessing

def worker(lock, shared_counter):
    for _ in range(100):
        with lock:
            shared_counter.value += 1

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

    processes = []
    for _ in range(2):
        process = multiprocessing.Process(target=worker, args=(lock, shared_counter))
        processes.append(process)
        process.start()

    for process in processes:
        process.join()

    print(f"Final counter value: {
     shared_counter.value}")

multiprocessing 和 threading 是 Python 中实现并发执行的两个模块,它们各自有不同的特性和适用场景。以下是它们之间的主要区别:

  1. 进程与线程
  • multiprocessing:
    (1)创建独立的进程,每个进程有自己的内存空间。
    (2)适合 CPU 密集型任务,因为可以充分利用多核 CPU。

  • threading:
    (1)创建线程,线程共享同一进程的内存空间。
    (2)适合 I/O 密集型任务,如网络请求、文件操作等,因为线程间的切换比进程更轻便。

  1. 资源占用
  • multiprocessing:
    进程之间相互独立,因此资源占用较高,启动和销毁进程的开销较大。

  • threading:
    线程之间共享内存,资源占用较低,启动和销毁线程的开销小。

  1. GIL (全局解释器锁)
  • multiprocessing:
    每个进程有自己的 Python 解释器和内存空间,因此不受 GIL 的限制,可以实现真正的并行处理。
  • threading:
    由于 GIL 的存在,Python 线程不能在多核 CPU 上实现真正的并行,因此在 CPU 密集型任务中性能较差。
  1. 进程间通信
  • multiprocessing:
    提供了多种方式进行进程间通信,例如队列 (Queue)、管道 (Pipe) 和共享内存等。
  • threading:
    由于线程共享内存,线程间通信相对简单,可以直接访问共享变量,但需要使用锁等同步机制来避免竞争条件。
  1. 适用场景
  • multiprocessing:
    适合 CPU 密集型任务,如数据处理、科学计算、图像处理等。
  • threading:
    适合 I/O 密集型任务,如网络爬虫、本地文件操作、数据库访问等。
  1. 错误处理
  • multiprocessing:
    由于进程之间相互独立,某个进程的崩溃不会影响其他进程。
  • threading:
    如果一个线程崩溃,可能会导致整个进程崩溃。

总结

  • 选择 multiprocessing: 当你的任务是 CPU 密集型时,使用 multiprocessing 模块以充分利用多核 CPU 的优势。
  • 选择 threading: 当你的任务是 I/O 密集型时,使用 threading 模块以更轻便的方式处理并发。

以下是一些使用 multiprocessing 模块的实际应用示例,展示如何在不同场景中利用多进程实现并行处理。

示例:图像处理

在图像处理任务中,可以使用多进程来并行处理多个图像文件。

import multiprocessing
from PIL import Image
import os

def process_image(image_path):
    with Image.open(image_path) as img:
        img = img.convert("L")  # 转换为灰度图像
        img.save(f"processed_{
     os<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AnFany

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值