Skip to content

8. 多进程开发

进程是计算机中资源分配的最小单元;一个进程中可以有多个线程,同一个进程中的线程共享资源。

进程与进程之间是相互独立的,进程之间的数据不共享。

python 中通过多进程可以利用CPU的多核优势,计算密集型操作适用于多进程开发。

进程创建

python
import multiprocessing


def task():
    pass


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

fork

在类 Unix 系统中,fork 是创建新进程的常用方法。fork 会拷贝当前进程的几乎所有资源到新进程中,包括打开的文件描述符、内存空间等。

支持文件对象/线程锁等传参。

拷贝主进程到新创建的子进程中。

python
import multiprocessing
import time


def task():
    print("子进程前", name)
    name.append(123)
    print("子进程后", name)


if __name__ == "__main__":
    multiprocessing.set_start_method("fork")
    name = []

    p1 = multiprocessing.Process(target=task)
    p1.start()

    time.sleep(1)
    print("主进程", name)  # 主进程的name没有被子进程修改

# 输出结果:
# 子进程前 []
# 子进程后 [123]
# 主进程 []

spawn 和 forkserver

在 unix, windows 使用 spawn 创建进程时,他不会完全拷贝主进程的资源例如(fork),他会将必备的资源通过传参将需要的资源传递给子进程。

在部分 unix 系统中,forkserver 会先启动一个“干净”的 server 进程由其 fork 出子进程(子进程的父进程为 server),随后主进程与子进程通过管道等 IPC 直接通信。

不支持文件对象/线程锁等传参。

python
import multiprocessing
import time


def task(name):
    print("子进程前", name)
    name.append(123)
    print("子进程后", name)


if __name__ == "__main__":
    multiprocessing.set_start_method("spawn")
    name = []

    p1 = multiprocessing.Process(target=task, args=(name,))
    p1.start()

    time.sleep(1)
    print("主进程", name)  # 主进程的name没有被子进程修改

进程常见方法

start()

当前进程准备就绪,等待被 CPU 调度(工作单元其实是进程中的线程)

join()

join(timeout=None) 阻塞当前进程,等待子进程结束,timeout 可设置等待时间

daemon

p.daemon = 布尔值:设置守护进程,必须放在start之前

  • p.daemon = True 设置为守护进程,主进程结束,守护进程也会结束
  • p.daemon = False 设置为非守护进程,主进程等待子进程,子进程执行完毕后,主进程才结束。

进程名称设置和获取

python
import multiprocessing
import os
import threading
import time


def task(arg):
    # 获取当前进程id,和父进程id
    print("进程id:", os.getpid(), "父进程id:", os.getppid())

    # 获取线程个数
    print("线程个数:", len(threading.enumerate()))
    time.sleep(2)
    # 获取进程名称
    print("当前进程的名称:", multiprocessing.current_process().name)


if __name__ == "__main__":
    multiprocessing.set_start_method("spawn")
    p = multiprocessing.Process(target=task, args=("xxx",))

    # 设置进程名称
    p.name = "哈哈哈哈"
    p.start()

    print("继续执行")

自定义进程类

直接将线程需要做的事写到 run 方法中

python
import multiprocessing


class MyProcess(multprocessing.Process):
    def run(self):
        print("执行此进程", self.args)


if __name__ == "__main__":
    multiprocessing.set_start_method("spawn")
    p = MyProcess(args=("xxx",))
    p.start()
    print("继续执行")

cpu_count()

计算cpu个数, 程序中一般 CPU 多少个,就创建多少个进程

python
import multiprocessing


def task(args):
    print("进程运行")


if __name__ == "__main__":
    count = multiprocessing.cpu_count()
    print("CPU个数:", count)

    # 因为主进程占一个
    for i in range(count - 1):
        p = multiprocessing.Process(target=task, args=("xxx",))
        p.start()

构建时间:11/21/2025, 1:28:39 PM | 本博客内容均为自己学习,如内容涉及侵权,请联系邮箱:pangzl0215@163.com