【Python】多进程的实现

124 阅读2分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。

《【Python】多线程的实现及其存在的问题》 一文中,讲解了如何在 Python 中使用多线程,以及 Python 多线程存在的问题——由于全局解释器锁的存在, Python 中的多线程实际上是假的多线程,不管有几个核,单位时间多个核只能跑一个线程。并提到了如果需要充分利用多核,可使用 multiprocessing 库,创建多进程。本文将介绍 Python 中多线程的实现。

multiprocessing

multiprocessing 库提供了基于进程的并行处理,通过使用子进程而非线程有效地绕过了全局解释器锁,因此,multiprocessing 库允许程序员充分利用给定机器上的多个处理器。

多进程的创建

在 multiprocessing 中,通过创建一个 Process 对象然后调用它的 start() 方法来生成进程。

import multiprocessing

if __name__ == '__main__':
    process = multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, daemon=None)
  • group :分组,仅用于兼容 threading.Thread,必须始终为 None,否则会抛出异常
  • target :这个进程实例所调用的对象
  • name : 进程的名称
  • args、kwargs :调用对象所需的参数
  • daemon :子线程是否为守护线程
    • 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流的最小单元,当设置多线程时,主线程会创建多个子线程
    • 默认情况下(None),该标志将从创建的进程继承
    • 设置为 False 时候,主线程执行完自己的任务以后退出,子线程会继续执行自己的任务,直到自己的任务结束
    • 设置为 True 时候,主线程一旦执行结束,则全部子线程全部被终止执行

进程的启动与停止

  • process.start() :启动进程
  • process.kill() :终止进程(使用SIGKILL信号)
  • process.terminate() :终止进程(使用SIGTERM信号)
  • porcess.close() :关闭进程,释放与之关联的所有资源
    • 如果底层进程仍在运行,则会引发 ValueError
  • process.join(timeout=None) :等待直到进程结束
    • timeout 为 None 时候,该方法将阻塞,直到调用 join() 方法的进程终止。
    • 如果 timeout 是一个正数,它最多会阻塞 timeout 秒
    • 如果进程终止或方法超时,则该方法返回 None 
  • process.is_alive() :返回进程是否还活着

举个栗子

import multiprocessing
import time

def hello():
    print("Hello")
    time.sleep(1)
    print("world")

if __name__ == '__main__':

    # daemon
    process = multiprocessing.Process(target= hello)
    process.start()
    # 输出 Hello world
    
    process = multiprocessing.Process(target= hello, daemon= True)
    process.start()
    # 输出 Hello
    
    # kill
    process = multiprocessing.Process(target= hello, daemon= True)
    process.start()
    time.sleep(0.2)
    process.kill()
    # 输出 Hello