当前位置:首页>python>Python-多任务与多进程

Python-多任务与多进程

  • 2026-09-10 13:32:10
Python-多任务与多进程
  多进程的核心意义是实现并行多任务,充分利用计算机多核 CPU 资源同时执行多个任务,大幅提升程序运行效率,还能通过独立进程空间隔离任务数据,避免单一线程阻塞拖慢整体程序。
# 知识点1:并发 vs 并行# ----------------------------------------------------------# · 并发(Concurrency):在一段时间内交替执行多个任务。#    单核 CPU 通过快速切换任务实现"看起来同时"的效果。# · 并行(Parallelism):在同一时刻真正同时执行多个任务。#    需要多核 CPU,每个核心独立运行一个任务。# · 类比:并发 = 一个人同时吃三个馒头,轮流咬;#         并行 = 三个人各吃一个馒头。# ----------------------------------------------------------# 知识点2:进程的概念# ----------------------------------------------------------# · 程序:保存在硬盘上的代码文件,是静态的(如 .py 文件)。# · 进程:程序被加载到内存中运行起来的实例,是动态的。# · 进程 = 操作系统进行资源分配和调度运行的基本单位。# · 每个进程拥有独立的内存空间,彼此不共享全局变量。# · 多进程适合 CPU 密集型任务(计算量大)。# ----------------------------------------------------------# 知识点3:__name__ 变量# ----------------------------------------------------------# · __name__ 是 Python 的内置变量,表示当前模块的名称。# · 当 .py 文件被直接运行时,__name__ = "__main__"# · 当 .py 文件被 import 导入时,__name__ = 文件名(不含 .py)# · 用途:区分"脚本直接运行"还是"被其他模块导入"。print(__name__)  # 直接运行本文件时输出 "__main__"if __name__ == "__main__":    # 知识点:这个 if 判断被称为"程序入口守卫"。    # 直接运行 → 条件满足,代码被执行    # 被 import → 条件不满足,代码被跳过(避免导入时意外执行)    print("执行的为当前文件")# ----------------------------------------------------------# 知识点4:multiprocessing 模块# ----------------------------------------------------------# · Python 内置的跨平台多进程模块。# · 核心类:Process — 代表一个进程对象。# · 核心方法:#     Process(target=函数名)  → 创建进程对象,绑定目标函数#     .start()                → 启动进程(会在新进程中执行 target 函数)#     .join()                 → 等待该进程结束(阻塞当前进程)#     .is_alive()             → 判断进程是否还在运行# import multiprocessing# import time## def sing():#     for i in range(3):#         print("sing")#         time.sleep(1)## def dance():#     for i in range(3):#         print("dance")#         time.sleep(1)## if __name__ == "__main__":#     # 创建两个进程对象#     sing_process = multiprocessing.Process(target=sing)#     dance_process = multiprocessing.Process(target=dance)##     # 启动进程:两个进程同时执行,互不阻塞#     sing_process.start()#     dance_process.start()##     # 对比:直接调用函数则是串行执行#     # sing()   # 等 sing 执行完才能执行 dance#     # dance()# ----------------------------------------------------------# 知识点5:多进程传参 — args 和 kwargs# ----------------------------------------------------------# · args:通过元组按位置传参,如 args=(4, "小明")# · kwargs:通过字典按关键字传参,如 kwargs={"num": 5, "name": "小红"}# · 二者可以同时使用:args 传位置参数,kwargs 传关键字参数。# · 注意:args 元组只有一个参数时,必须加逗号 args=(42,),#    否则 (42) 会被当作括号表达式而非元组。# import multiprocessing# import time## def sing(num, name):#     for i in range(3):#         print(f"{name} sing {num}")#         time.sleep(1)## def dance(num, name):#     for i in range(3):#         print(f"{name} dance {num}")#         time.sleep(1)## if __name__ == "__main__":#     # 元组传参 (args),按位置匹配#     sing_process = multiprocessing.Process(target=sing, args=(4, "小明"))#     # 字典传参 (kwargs),按键名匹配#     dance_process = multiprocessing.Process(#         target=dance, kwargs={"num": 5, "name": "小红"}#     )#     sing_process.start()#     dance_process.start()# ----------------------------------------------------------# 知识点6:进程编号 — os.getpid() 与 os.getppid()# ----------------------------------------------------------# · os.getpid()  :获取当前进程的 ID(PID),操作系统唯一标识。# · os.getppid() :获取当前进程的父进程 ID。# · 主进程:执行 python 命令的那个进程。# · 子进程:由主进程通过 Process 创建出来的进程。# · 每个子进程的 ppid 就是主进程的 pid。# import multiprocessing# import time# import os## def work(num, name):#     print(f"子进程 PID={os.getpid()}, 父进程 PPID={os.getppid()}")#     for i in range(3):#         print(f"{name} work {num}")#         time.sleep(1)## if __name__ == "__main__":#     print(f"主进程 PID={os.getpid()}")#     p = multiprocessing.Process(target=work, args=(1, "任务"))#     p.start()# ----------------------------------------------------------# 知识点7:守护进程 — daemon# ----------------------------------------------------------# · 默认行为:主进程会等待所有子进程执行完毕后才退出。# · 守护进程:主进程退出时,守护子进程会立即被终止,不管有没有执行完。# · 设置方式有两种(效果相同):#     方式一:Process(target=..., daemon=True)    ← 构造时传入#     方式二:p.daemon = True                     ← 设置属性(必须在 start() 之前)# · 适用场景:后台日志、监控心跳、临时辅助任务(主任务结束就无需再跑)。# import multiprocessing# import time## def chat(num, name):#     for i in range(num):#         print(f"和 {name} 聊天")#         time.sleep(0.2)## if __name__ == "__main__":#     # 方式一:构造函数直接设置 daemon=True#     # chat_process = multiprocessing.Process(target=chat, args=(10, "小明"), daemon=True)##     # 方式二:先创建对象,再设置 daemon 属性(必须在 start() 之前设置)#     chat_process = multiprocessing.Process(target=chat, args=(10, "小明"))#     chat_process.daemon = True       # 必须在 start() 之前设置,否则报错#     chat_process.start()##     time.sleep(1)                    # 主进程等 1 秒#     print("主进程结束")               # 主进程结束后,守护子进程自动终止#     # 如果不设 daemon,即使打印了"主进程结束",子进程还会继续跑完 10 次#     # 设置了 daemon 后,"主进程结束"打印后子进程立即消失# ----------------------------------------------------------# 知识点8(补充):进程不共享全局变量# ----------------------------------------------------------# · 每个子进程拥有独立的内存空间,全局变量不会在进程间共享。# · 子进程修改全局变量,主进程和其他子进程都看不到。# · 这是多进程与多线程的关键区别之一。# · 如需进程间通信,使用 Queue、Pipe、Manager 等。

最新文章

随机文章