Python多进程与多线程实战:Process与Thread的使用及守护模式

Noah
Noah
发布时间:2026-10-15| 4人浏览过
原创

本文详解Python中多进程与多线程的核心用法。通过Process和Thread类演示任务创建、启动及参数传递(元组与字典),并重点讲解daemon守护模式的两种配置方式。结合代码示例与运行输出,对比分析主进程/线程结束时对子任务的影响,帮助开发者掌握并发编程基础。

进程与线程基础概念

可以将计算机资源比作学校机房:固定数量的电脑对应CPU核心,每台电脑代表一个进程。老师分配爬虫任务,每个学生用一台电脑爬取部分数据并存入公共数据库,这里公共数据库即共享资源。若一台电脑开启多个爬虫实例,则相当于一个进程内包含多个线程,线程数量受限于该电脑的运行内存。总结而言,单个CPU可运行多个进程,而每个进程内部可包含一个或多个线程。

多进程编程实现

第一步:导入所需模块


from multiprocessing import Process

第二步:定义两个独立的任务函数

第三步:实例化进程对象。语法为:进程变量名 = Process(target=函数名, args=参数元组或kwargs=参数字典, daemon=是否守护进程)

第四步:调用进程变量的start()方法以启动进程。

第五步:配置守护进程行为。默认情况下,主进程会等待所有子进程执行完毕后才退出。若希望主进程结束后立即销毁未完成的子进程并关闭程序,可通过两种方式设置守护模式:1. 在创建Process时传入参数daemon=True;2. 在进程对象创建后,设置属性进程变量名.daemon=True。

第六步:获取当前进程ID。需导入os模块,使用os.getpid()获取当前进程编号。


os.getpid()

获取当前父进程ID,使用os.getppid()函数。


os.getppid()

代码示例:未开启进程守护模式


from multiprocessing import Process
import time
import os

# 一个写作业函数
def homeWork(name, count):
  for i in range(count):
    # 打印当前进程编号os.getpid()
    print("当前进程编号:", os.getpid())

    # 打印当前父进程编号os.getppid()
    print("当前父进程编号:", os.getppid())

    print(name, "正在写作业...")
    time.sleep(0.2)
# 一个打游戏函数
def game(name, count):
  for i in range(count):
    # 打印当前进程编号os.getpid()
    print("当前进程编号:", os.getpid())

    # 打印当前父进程编号os.getppid()
    print("当前父进程编号:", os.getppid())

    print(name, "正在打游戏...")
    time.sleep(0.2)

if __name__ == '__main__':
  # 打印当前进程编号os.getpid()
  print("当前进程编号:", os.getpid())

  # 进程1写作业 元组传参
  p1 = Process(target=homeWork, args=("进程1", 10))
  # 进程2打游戏 字典传参
  p2 = Process(target=game, kwargs={"name": "进程2", "count": 10})

  # 启动进程
  p1.start()
  p2.start()
  time.sleep(1)
  print("主进程结束---------------------------------------------")

未开启守护模式的运行结果分析

# 观察输出可见,主进程结束后,其子进程仍在继续执行。 当前进程编号: 14972 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 主进程结束--------------------------------------------- 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏... 当前进程编号: 5732 当前父进程编号: 14972 进程1 正在写作业... 当前进程编号: 14752 当前父进程编号: 14972 进程2 正在打游戏...

Process finished with exit code 0

代码示例:开启进程守护模式


from multiprocessing import Process
import time
import os

# 一个写作业函数
def homeWork(name, count):
  for i in range(count):
    # 打印当前进程编号os.getpid()
    print("当前进程编号:", os.getpid())

    # 打印当前父进程编号os.getppid()
    print("当前父进程编号:", os.getppid())

    print(name, "正在写作业...")
    time.sleep(0.2)
# 一个打游戏函数
def game(name, count):
  for i in range(count):
    # 打印当前进程编号os.getpid()
    print("当前进程编号:", os.getpid())

    # 打印当前父进程编号os.getppid()
    print("当前父进程编号:", os.getppid())

    print(name, "正在打游戏...")
    time.sleep(0.2)

if __name__ == '__main__':
  # 打印当前进程编号os.getpid()
  print("当前进程编号:", os.getpid())

  # 进程1写作业 元组传参 第一种方法启动进程守护
  p1 = Process(target=homeWork, args=("进程1", 10), daemon=True)
  # 进程2打游戏 字典传参
  p2 = Process(target=game, kwargs={"name": "进程2", "count": 10})
  # 第二种
  p2.daemon = True
  # 启动进程
  p1.start()
  p2.start()
  time.sleep(1)
  print("主进程---------------------------------------------")

开启守护模式的运行结果分析

当前进程编号: 372 当前进程编号: 10116 当前进程编号: 9860 当前父进程编号: 372 进程1 正在写作业... 当前父进程编号: 372 进程2 正在打游戏... 当前进程编号: 9860 当前进程编号: 10116 当前父进程编号: 372 进程2 正在打游戏... 当前父进程编号: 372 进程1 正在写作业... 当前进程编号: 9860 当前进程编号: 10116 当前父进程编号: 372 进程1 正在写作业... 当前父进程编号: 372 进程2 正在打游戏... 当前进程编号: 9860 当前进程编号: 10116 当前父进程编号: 372 进程1 正在写作业... 当前父进程编号: 372 进程2 正在打游戏... 主进程结束---------------------------------------------

Process finished with exit code 0

多线程编程实现

第一步:导入threading模块


import threading

第二步:定义两个独立的任务函数

第三步:实例化线程对象。语法为:线程变量名 = threading.Thread(target=函数名, args=参数元组或kwargs=参数字典, daemon=是否守护进程)

第四步:调用线程变量的start()方法以启动线程。

第五步:配置守护线程行为。默认情况下,主程序会等待所有子线程执行完毕后才退出。若希望主程序结束后立即销毁未完成的子线程并关闭程序,可通过两种方式设置守护模式:1. 在创建Thread时传入参数daemon=True;2. 在线程对象创建后,设置属性线程变量名.daemon=True。

第六步:获取当前线程对象。使用threading.current_thread()获取当前线程编号或对象信息。


threading.current_thread()

代码示例:未开启线程守护模式


import threading
import time

# 一个写作业函数
def homeWork(name, count):
  for i in range(count):
    # 打印当前线程
    print(threading.current_thread())
    print(name, "正在写作业...")
    time.sleep(0.2)
# 一个打游戏函数
def game(name, count):
  for i in range(count):
    # 打印当前线程
    print(threading.current_thread())
    print(name, "正在打游戏...")
    time.sleep(0.2)

if __name__ == '__main__':

  # 线程1写作业 元组传参
  t1 = threading.Thread(target=homeWork, args=("进程1", 10))
  # 线程2打游戏 字典传参
  t2 = threading.Thread(target=game, kwargs={"name": "进程2", "count": 10})

  # 启动进程
  t1.start()
  t2.start()
  time.sleep(1)
  print("主进程结束###################################################################################")

未开启守护模式的运行结果分析

# 观察输出可见,主进程结束后,其线程仍在继续执行。 <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-2, started 9100)> 进程2 正在打游戏... <Thread(Thread-2, started 9100)> 进程2 正在打游戏... <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-2, started 9100)> 进程2 正在打游戏... <Thread(Thread-2, started 9100)> 进程2 正在打游戏... <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-2, started 9100)> 进程2 正在打游戏... 主进程结束################################################################################### <Thread(Thread-2, started 9100)> 进程2 正在打游戏... <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-1, started 3364)> <Thread(Thread-2, started 9100)> 进程2 正在打游戏...进程1 正在写作业... <Thread(Thread-1, started 3364)> 进程1 正在写作业... <Thread(Thread-2, started 9100)> 进程2 正在打游戏... <Thread(Thread-2, started 9100)><Thread(Thread-1, started 3364)> 进程1 进程2正在写作业... 正在打游戏... <Thread(Thread-2, started 9100)><Thread(Thread-1, started 3364)>

进程2 进程1 正在打游戏... 正在写作业...

Process finished with exit code 0

代码示例:开启线程守护模式


import threading
import time

# 一个写作业函数
def homeWork(name, count):
  for i in range(count):
    # 打印当前线程
    print(threading.current_thread())
    print(name, "正在写作业...")
    time.sleep(0.2)
# 一个打游戏函数
def game(name, count):
  for i in range(count):
    # 打印当前线程
    print(threading.current_thread())
    print(name, "正在打游戏...")
    time.sleep(0.2)

if __name__ == '__main__':

  # 线程1写作业 元组传参
  t1 = threading.Thread(target=homeWork, args=("进程1", 10), daemon=True)
  # 线程2打游戏 字典传参
  t2 = threading.Thread(target=game, kwargs={"name": "进程2", "count": 10})
  t2.daemon = True

  # 启动进程
  t1.start()
  t2.start()
  time.sleep(1)
  print("主进程结束###################################################################################")

开启守护模式的运行结果分析

<Thread(Thread-1, started daemon 15480)> 进程1 正在写作业... <Thread(Thread-2, started daemon 13700)> 进程2 正在打游戏... <Thread(Thread-2, started daemon 13700)> 进程2 正在打游戏... <Thread(Thread-1, started daemon 15480)> 进程1 正在写作业... <Thread(Thread-1, started daemon 15480)><Thread(Thread-2, started daemon 13700)> 进程1 进程2 正在写作业...正在打游戏...

<Thread(Thread-2, started daemon 13700)><Thread(Thread-1, started daemon 15480)>

进程1进程2 正在写作业... 正在打游戏...

<Thread(Thread-1, started daemon 15480)> 进程1 正在写作业... <Thread(Thread-2, started daemon 13700)> 进程2 正在打游戏... 主进程结束###################################################################################

Process finished with exit code 0

本文介绍了Python中多进程与多线程的基本使用方法。如需了解更多Python多进程与多线程相关内容,建议查阅本站过往文章或继续浏览后续教程。感谢大家的支持!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。