【Python多进程】的进阶讲解

发布于:2024-03-18 ⋅ 阅读:(271) ⋅ 点赞:(0)

1. 介绍

Python中的多进程是通过multiprocessing模块来实现的,与多线程相比,多进程可以实现真正的并行计算,因为每个进程拥有自己的Python解释器和内存空间,因此不会受全局解释器锁(Global Interpreter Lock, GIL)的限制。

2. multiprocessing模块的基本用法

基本上,multiprocessing模块的Process类与threading模块的Thread类的使用非常相似。下面是一个简单的例子,说明如何创建和启动一个进程:

from multiprocessing import Process
import os

# 子进程要执行的代码
def run_proc(name):
    print(f'Run child process {name} ({os.getpid()})...')

if __name__=='__main__':
    print(f'Parent process {os.getpid()}.')
    p = Process(target=run_proc, args=('test',))
    print('Child process will start.')
    p.start()
    p.join()
    print('Child process end.')

当我们运行上面的代码,将会创建一个子进程,执行run_proc函数中的代码。

3. 使用Pool

如果你要启动大量的子进程,可以用进程池的方式批量创建子进程:

from multiprocessing import Pool
import time

def run_task(name):
    print(f"Task {name} (pid = {os.getpid()}) is running...")
    time.sleep(1)
    print(f"Task {name} is end.")

if __name__ == '__main__':
    print("Parent process is run.")
    with Pool(5) as p:  # 创建拥有5个进程的进程池
        p.map(run_task, range(5))
    print("All subprocesses done.")

这里使用了Pool对象的map方法将不同的参数传入到目标函数(此例中为run_task)并并行执行函数。

4. 进程间通信

multiprocessing支持进程间的两种主要通信方式:队列(Queue)和管道(Pipe)。

from multiprocessing import Queue

# 创建Queue的实例,然后使用Queue来进行进程间的通信
q = Queue()
q.put('Message 1')
q.put('Message 2')
print(q.get())

5. 进程同步

在多进程环境下,由于进程间共享资源可能会导致数据混乱,因此需要对这些资源进行同步访问控制。multiprocessing模块中的Lock类就是用来解决这一问题的:

from multiprocessing import Process, Lock

def lock_func(lock, num):
    lock.acquire()
    try:
        print(f'Hello from process {num}')
    finally:
        lock.release()

if __name__=="__main__":
    lock = Lock()
    for num in range(5):
        Process(target=lock_func, args=(lock, num)).start()

6. Process子类化

threading.Thread类似,你也可以通过继承multiprocessing.Process来创建自己的进程类:

from multiprocessing import Process

class MyProcess(Process):
    def __init__(self, arg):
        super(MyProcess, self).__init__()
        self.arg = arg

    def run(self):
        print(f'Process with argument: {self.arg}')

if __name__=='__main__':
    p = MyProcess('test')
    p.start()
    p.join()

MyProcess实例的start()方法被调用时,其run()方法将在独立的子进程中执行。

7. 注意事项及选择

在使用多进程时需要考虑一些事情:

  • 因为进程之间的内存是隔离的,所以它们必须通过进程间通信来交换信息,这可能会导致程序复杂。
  • 创建进程比创建线程的开销大,所以需要更多的系统资源。
  • 在多核/多处理器环境下,多进程是真正实现并行计算的一种方式。

选择使用多线程还是多进程通常取决于任务特性和需求:

  • 涉及阻塞I/O操作或需等待外部事件(如网络通信、文件I/O)的任务,使用多线程比较适合。
  • 如果任务是计算密集型的(如数学计算、数据处理),并且需要进行并行处理,那么多进程更为合适。

总之,Python的多进程编程提供了对并行任务处理的强大支持,特别是在避免GIL限制的情况下有效利用多核处理器。然而,正确地使用它需要对进程间通信、数据共享和同步有透彻的理解。

本文含有隐藏内容,请 开通VIP 后查看

网站公告


今日签到

点亮在社区的每一天
去签到