Python 多进程启动方式

Python 多进程启动方式

Python 多进程启动方式

1. 前言

在编写程序时,有时候需要同时执行多个任务。Python 提供了多种启动多进程的方式,本文将详细介绍这些启动方式,并给出示例代码。

2. 使用 multiprocessing 模块启动多进程

Python 的标准库中提供了 multiprocessing 模块,可以方便地启动多个子进程。它与常用的 threading 模块类似,但是能够充分利用多核 CPU 进行并行计算。

2.1. 创建子进程

使用 multiprocessing 模块,我们首先需要创建一个子进程。可以通过创建 Process 对象来实现:

import multiprocessing

def worker():
    print(f"子进程 ID: {multiprocessing.current_process().pid}")

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

运行上述代码,会创建一个子进程并打印出子进程的 ID。Process 类的构造函数接受一个 target 参数,指定子进程要执行的函数。start() 方法启动子进程,join() 方法等待子进程执行完毕。

输出结果示例:

子进程 ID: 12345

2.2. 启动多个子进程

上述例子只启动了一个子进程,如果需要启动多个子进程,可以使用循环语句进行多次创建和启动。下面的示例代码创建了 4 个子进程,并打印出每个子进程的 ID:

import multiprocessing

def worker():
    print(f"子进程 ID: {multiprocessing.current_process().pid}")

if __name__ == "__main__":
    processes = []
    for i in range(4):
        p = multiprocessing.Process(target=worker)
        processes.append(p)
        p.start()

    for p in processes:
        p.join()

输出结果示例:

子进程 ID: 12345
子进程 ID: 12346
子进程 ID: 12347
子进程 ID: 12348

2.3. 传递参数给子进程

有时候,我们需要在主进程中定义一些数据,并将这些数据传递给子进程。可以通过在创建 Process 对象时传递参数来实现。

import multiprocessing

def worker(num):
    print(f"子进程 ID: {multiprocessing.current_process().pid}")
    print(f"传入的参数: {num}")

if __name__ == "__main__":
    processes = []
    for i in range(4):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()

    for p in processes:
        p.join()

输出结果示例:

子进程 ID: 12345
传入的参数: 0
子进程 ID: 12346
传入的参数: 1
子进程 ID: 12347
传入的参数: 2
子进程 ID: 12348
传入的参数: 3

3. 使用 concurrent.futures 模块启动多进程

Python 3 中引入了 concurrent.futures 模块,它提供了更高级的接口,更方便地启动多个子进程。

3.1. 创建并行进程池

可以使用 concurrent.futures 模块的 ProcessPoolExecutor 类创建并行进程池。下面的示例代码创建了一个进程池并使用 submit() 方法向进程池中提交任务:

import concurrent.futures

def worker(num):
    print(f"子进程 ID: {multiprocessing.current_process().pid}")
    return num * 2

if __name__ == "__main__":
    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = [executor.submit(worker, i) for i in range(4)]

        for future in concurrent.futures.as_completed(results):
            result = future.result()
            print(f"子进程返回结果: {result}")

输出结果示例:

子进程 ID: 12345
子进程 ID: 12346
子进程 ID: 12347
子进程 ID: 12348
子进程返回结果: 0
子进程返回结果: 2
子进程返回结果: 4
子进程返回结果: 6

3.2. 使用 map() 方法启动多个子进程

ProcessPoolExecutor 类还提供了 map() 方法,可以用于启动多个子进程,并同时传递多个参数。下面的示例代码演示了如何使用 map() 方法:

import concurrent.futures

def worker(num1, num2):
    print(f"子进程 ID: {multiprocessing.current_process().pid}")
    return num1 + num2

if __name__ == "__main__":
    with concurrent.futures.ProcessPoolExecutor() as executor:
        params = [(1, 2), (3, 4), (5, 6), (7, 8)]
        results = executor.map(worker, *zip(*params))

        for result in results:
            print(f"子进程返回结果: {result}")

输出结果示例:

子进程 ID: 12345
子进程 ID: 12346
子进程 ID: 12347
子进程 ID: 12348
子进程返回结果: 3
子进程返回结果: 7
子进程返回结果: 11
子进程返回结果: 15

4. 使用 subprocess 模块启动外部进程

除了启动 Python 子进程,我们还可以使用 subprocess 模块启动外部进程。这对于执行一些系统命令或调用其他语言编写的程序非常有用。

import subprocess

def main():
    print("启动外部进程")
    subprocess.run(["ls", "-l"])
    print("外部进程执行完毕")

if __name__ == "__main__":
    main()

运行上述代码,会在终端中执行 ls -l 命令,并将结果输出。然后打印出 “外部进程执行完毕”。

5. 总结

本文介绍了在 Python 中启动多进程的几种常用方式:使用 multiprocessing 模块创建子进程,使用 concurrent.futures 模块创建并行进程池,以及使用 subprocess 模块启动外部进程。通过灵活使用多进程,我们可以提高程序的运行效率和性能。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程