multiprocessing-并发编程-Python


multiprocessing 是 Python 标准库中的一个模块,用于支持并行计算。它能够通过创建多个进程来实现任务的并行执行,从而充分利用多核处理器的优势,提高程序的执行效率。

这里是一些 multiprocessing 常见用法:

1. 创建并启动多个进程

import multiprocessing

def worker(num):
    print(f"Worker {num} is working")

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()

2. 使用 Pool 来管理进程池

Pool 提供了一种方便的方法来并行执行多个任务。它通过在一个池中管理多个工作进程来并行处理任务。

import multiprocessing

def square(x):
    return x * x

if __name__ == "__main__":
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(square, [1, 2, 3, 4, 5])
    print(results)

3. 进程间通信(Queue, Pipe)

使用 Queue 进行进程间通信:

import multiprocessing

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

if __name__ == "__main__":
    queue = multiprocessing.Queue()
    p = multiprocessing.Process(target=worker, args=(queue,))
    p.start()
    p.join()

    print(queue.get())  # 输出:Hello from worker

使用 Pipe 进行进程间通信:

import multiprocessing

def worker(conn):
    conn.send("Hello from worker")
    conn.close()

if __name__ == "__main__":
    parent_conn, child_conn = multiprocessing.Pipe()
    p = multiprocessing.Process(target=worker, args=(child_conn,))
    p.start()
    p.join()

    print(parent_conn.recv())  # 输出:Hello from worker

4. 共享数据

multiprocessing 提供了 ValueArray 这两种方式来共享数据。

import multiprocessing

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

if __name__ == "__main__":
    counter = multiprocessing.Value('i', 0)  # 'i' 表示整数
    processes = []

    for _ in range(5):
        p = multiprocessing.Process(target=increment, args=(counter,))
        processes.append(p)
        p.start()

    for p in processes:
        p.join()

    print(f"Counter value: {counter.value}")

5. 使用 Manager 来共享复杂对象

Manager 可以用来创建共享的复杂数据类型,如列表、字典等。

import multiprocessing

def worker(shared_list):
    shared_list.append(1)

if __name__ == "__main__":
    with multiprocessing.Manager() as manager:
        shared_list = manager.list()

        processes = []
        for _ in range(5):
            p = multiprocessing.Process(target=worker, args=(shared_list,))
            processes.append(p)
            p.start()

        for p in processes:
            p.join()

        print(shared_list)  # 输出:[1, 1, 1, 1, 1]

6. 注意事项

  • 多进程 vs 多线程multiprocessing 创建的是独立的进程,每个进程有自己的内存空间,因此不会出现线程中的“全局解释器锁(GIL)”问题。
  • 跨平台multiprocessing 在 Windows 和 Linux 上表现不同,尤其是在进程启动方式上。在 Windows 上,进程是通过spawn启动的,而在 Linux 上则是通过fork启动。
  • 进程创建开销:启动一个进程相对较慢,通常适合任务比较重的场景。如果任务较轻,使用 Threading 或异步编程(如 asyncio)可能更合适。

如果你有特定的应用场景或者遇到问题,告诉我,我可以帮助你更具体地解决。