Python多任务编程:进程全面详解与实战指南

1. 进程基础概念

1.1 什么是进程?

进程(Process)是指正在执行的程序,是程序执行过程中的一次指令、数据集等的集合。简单来说,进程就是程序的一次执行过程,它是一个动态的概念。

想象你打开电脑上的音乐播放器听歌,同时又在用浏览器上网,这两个就是不同的进程。操作系统会为每个运行的程序创建一个进程,让它们看起来像是同时在运行。

1.2 进程的特征

  • 动态性:进程有创建、执行、暂停、终止等生命周期

  • 并发性:多个进程可以同时存在于内存中,在一段时间内交替执行

  • 独立性:每个进程拥有独立的地址空间和系统资源

  • 异步性:进程执行速度不可预知,可能随时被中断

1.3 进程与程序的区别

区别点程序进程
状态静态的代码集合动态的执行过程
生命周期永久保存暂时存在
资源占用不占用系统资源占用CPU、内存等资源

2. 进程调度算法

操作系统使用调度算法决定哪个进程可以使用CPU资源:

2.1 先来先服务(FCFS)

  • 按照进程到达的顺序执行

  • 简单但不利于短作业

  • 示例:排队买票,先到先得

processes = ["P1", "P2", "P3"]
for p in processes:print(f"正在执行{p}")

2.2 短作业优先(SJF)

  • 优先执行预计运行时间短的进程

  • 能减少平均等待时间

  • 但难以准确预估作业长度

processes = [("P1",3), ("P2",1), ("P3",2)]
processes.sort(key=lambda x: x[1])  # 按执行时间排序

2.3 时间片轮转(RR)

  • 每个进程分配一个时间片(如100ms)

  • 时间片用完就切换到下一个进程

  • 公平但上下文切换开销大

from collections import deque
ready_queue = deque(["P1", "P2", "P3"])
time_slice = 1  # 单位时间while ready_queue:p = ready_queue.popleft()print(f"执行{p} {time_slice}单位时间")ready_queue.append(p)  # 重新加入队列

2.4 多级反馈队列

  • 结合了多种算法的优点

  • 设置多个优先级不同的队列

  • 新进程进入高优先级队列

  • 长时间运行的进程会被移到低优先级队列

3. 进程的并行与并发

3.1 基本概念

并行(Parallelism)
指多个任务真正同时执行,需要多核CPU支持。就像餐厅有多个厨师同时做不同的菜。

# 并行示例(假设4核CPU)
from multiprocessing import Pooldef task(n):return n * nif __name__ == '__main__':with Pool(4) as p:  # 创建4个进程print(p.map(task, [1, 2, 3, 4]))  # 4个任务真正同时执行

并发(Concurrency)
指多个任务交替执行,在单核CPU上通过快速切换实现"看似同时"。就像一个厨师轮流做多道菜。

# 并发示例
from multiprocessing import Process
import timedef task(name):print(f"{name}开始")time.sleep(1)print(f"{name}结束")if __name__ == '__main__':processes = []for i in range(3):  # 单核CPU上交替执行p = Process(target=task, args=(f"任务{i}",))p.start()processes.append(p)for p in processes:p.join()

3.2 关键区别

特性并行并发
硬件要求需要多核CPU单核即可
执行方式真正同时执行交替执行
效率更高(理想情况)相对较低
适用场景CPU密集型任务I/O密集型任务
图示🟢🟢🟢(同时进行)🟢→🟡→🔴(快速切换)

3.3 Python中的实现特点

  • GIL限制:由于全局解释器锁(GIL),Python多线程无法实现真正的并行,多进程是Python实现并行的主要方式

  • 进程开销:进程创建和上下文切换开销比线程大,适合CPU密集型任务

  • multiprocessing模块:绕过GIL限制,充分利用多核CPU

4. 同步/异步与阻塞/非阻塞

4.1 进程的三种基本状态

4.2 同步 vs 异步

同步(Synchronous)

  • 像排队买奶茶,必须等前一个人完成才能轮到你

  • 代码示例:

from multiprocessing import Process, Lockdef sync_task(lock, num):with lock:  # 同步锁print(f"进程{num}开始工作")time.sleep(1)print(f"进程{num}结束")if __name__ == '__main__':lock = Lock()for i in range(3):Process(target=sync_task, args=(lock, i)).start()

异步(Asynchronous)

  • 像取号等餐,拿到号后可以去做其他事

  • 代码示例:

from multiprocessing import Pooldef async_task(num):print(f"开始异步任务{num}")time.sleep(1)return num * 10if __name__ == '__main__':with Pool(3) as p:results = [p.apply_async(async_task, (i,)) for i in range(3)]for res in results:print(res.get())  # 需要时才获取结果

4.3 阻塞 vs 非阻塞

阻塞(Blocking)

  • 像打电话订餐,必须等客服回应才能做下一件事

  • 典型表现:join()get()等方法会阻塞

p = Process(target=time.sleep, args=(5,))
p.start()
p.join()  # 这里主程序会阻塞等待
print("子进程结束")

非阻塞(Non-blocking)

  • 像发短信订餐,发完就可以做其他事

  • 典型表现:不调用join()或使用Queuenowait

processes = []
for i in range(3):p = Process(target=time.sleep, args=(i,))p.start()processes.append(p)# 主进程继续执行其他代码...
print("主进程继续运行")# 最后再统一等待
for p in processes:p.join()

4.4 四种组合模式(重点理解)

  1. 同步阻塞

    • 最传统的方式

    • 示例:直接函数调用,等待返回结果

    result = time.sleep(3)  # 同步调用,阻塞等待
  2. 同步非阻塞

    • 轮询检查状态

    • 示例:检查进程是否完成

    while True:if not p.is_alive():breaktime.sleep(0.1)
  3. 异步阻塞

    • 较少使用

    • 示例:使用回调但主线程等待

    def callback(result):print("回调结果:", result)with Pool() as pool:res = pool.apply_async(func, args, callback=callback)res.wait()  # 这里又变成了阻塞

  4. 异步非阻塞

    • 最高效的方式

    • 示例:使用进程池+回调

    def callback(result):print("Got result:", result)with Pool() as pool:for i in range(5):pool.apply_async(func=time.sleep,args=(1,),callback=callback)print("主进程继续执行...")pool.close()pool.join()

4.5 实际应用场景建议

模式适用场景Python实现方式
同步阻塞简单线性任务直接函数调用
同步非阻塞需要轮询的任务循环检查is_alive()
异步阻塞较少使用apply_async+wait()
异步非阻塞高并发I/O操作进程池+回调函数

4.6  完整代码示例(综合应用)

"""
多进程模式下载器示例
演示并行、异步非阻塞模式
"""
from multiprocessing import Pool
import time
import randomdef download(url):print(f"开始下载 {url}")time.sleep(random.uniform(1, 3))  # 模拟下载时间print(f"完成下载 {url}")return f"{url}_内容"def save_content(result):print(f"保存结果: {result}")if __name__ == '__main__':urls = ["http://example.com/1","http://example.com/2","http://example.com/3","http://example.com/4"]with Pool(4) as pool:  # 创建进程池# 异步非阻塞模式提交任务results = [pool.apply_async(download, (url,), callback=save_content) for url in urls]print("主进程可以继续处理其他任务...")# 最终等待所有任务完成pool.close()pool.join()print("所有下载任务完成!")

这个示例展示了:

  1. 并行执行(4个下载任务同时进行)

  2. 异步非阻塞模式(提交任务后立即继续执行)

  3. 回调机制(下载完成后自动保存)

5. Python中的进程操作

Python通过multiprocessing模块实现多进程编程,下面介绍几种创建进程的方式。

5.1 方式一:使用Process类直接创建

from multiprocessing import Process
import osdef func(num):print(f"这是一个普通方法{num}")print(f"我是子进程,我的pid:{os.getpid()},我的父进程编号:{os.getppid()}")if __name__ == '__main__':# 创建进程对象p1 = Process(name="路飞", target=func, args=(1,))# 启动进程p1.start()# 输出父进程信息print(f"我是父进程,我的pid:{os.getpid()},我的父进程编号:{os.getppid()}")print(p1)

代码解析

  1. 导入Process类和os模块

  2. 定义目标函数func,它将在子进程中执行

  3. 创建Process实例,指定目标函数和参数

  4. 调用start()方法启动进程

  5. os.getpid()获取当前进程ID,os.getppid()获取父进程ID

5.2 方式二:继承Process类创建

from multiprocessing import Process
import osclass MyProcess(Process):def __init__(self, *args):super(MyProcess, self).__init__()self.args = argsdef run(self):print(f"我是子进程{self.args[0]}")if __name__ == '__main__':p1 = MyProcess(1)p2 = MyProcess(2)p3 = MyProcess(3)p1.start()p2.start()p3.start()

代码解析

  1. 自定义类继承Process

  2. 重写run()方法,定义进程执行逻辑

  3. 创建自定义类的实例并启动

  4. 这种方式更面向对象,适合复杂任务

5.3 进程常用方法

from multiprocessing import Process
import timedef fun():print("我是子进程")for i in range(3):time.sleep(5)print(f"我是子进程{i}")if __name__ == '__main__':p1 = Process(name='路飞', target=fun)p1.start()p1.join()  # 父进程等待子进程结束for i in range(2):time.sleep(1)print(f"我是父进程{i}")

关键方法

  • p.start()启动进程,并调用该子进程中的p.run()

  •  p.run ()进程启动时运行的方法,正是它去调用target 指定的函数,我们自定义类的类中一定要实现该方法
  • p.join([timeout])主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。

    timeout 是可选的超时时间,需要强调的是, p.join 只能 join start 开启的进程,而不能 join run 开启的进程
  • p.is_alive()如果p仍然运行,返回True

  • p.terminate()强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进 程。使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁

5.4 进程常用属性

from multiprocessing import Process
import timedef fun():for i in range(10):time.sleep(1)print("我是子进程")if __name__ == '__main__':p = Process(target=fun)p.daemon = True  # 设置为守护进程p.start()time.sleep(5)print("我是父进程")

重要属性

  • daemon默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时, p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置

    守护进程:跟随着父进程的代码执行结束,守护进程就结束
  • name:进程名称

  • pid:进程ID

  • exitcode进程在运行时为None、如果为–N,表示被信号N结束(了解即可)

6. 进程同步与通信

6.1 进程间数据隔离

from multiprocessing import Processdef work():global nn = 0print('子进程内: ', n)if __name__ == '__main__':n = 100p = Process(target=work)p.start()print('主进程内: ', n)

输出结果

主进程内: 100
子进程内: 0

解释:进程间内存空间独立,修改子进程中的变量不会影响父进程。

7. 实际应用建议

  1. CPU密集型任务:适合使用多进程,可以充分利用多核CPU

  2. I/O密集型任务:多线程可能更合适,避免进程创建开销

  3. 守护进程:用于执行后台任务,如日志记录、监控等

  4. 进程池:当需要创建大量进程时,考虑使用Pool

8. 注意事项

  1. Windows平台必须使用if __name__ == '__main__':保护主代码

  2. 进程创建和销毁开销较大,不宜创建过多进程

  3. 进程间通信需要使用队列(Queue)或管道(Pipe)等机制

  4. 避免僵尸进程(子进程结束但父进程未回收资源)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/902222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 网络基础(二) (传输协议层:UDP、TCP)

目录 一、传输层的意义 二、端口号 1、五元组标识一个通信 2、端口号范围划分 3、知名端口号(Well-Know Port Number) (1)查看端口号 4、绑定端口号数目问题 5、pidof & netstat 命令 (1)ne…

得佳胜哲讯科技 SAP项目启动会:胶带智造新起点 数字转型新征程

在全球制造业加速向数字化、智能化转型的浪潮中,胶带制造行业正迎来以“自动化生产、数据化运营、智能化决策”为核心的新变革。工业互联网、大数据分析与智能装备的深度融合,正推动胶带制造从传统生产模式向“柔性化生产精准质量控制全链路追溯”的智慧…

大数据学习栈记——MapReduce技术

本文介绍hadoop中的MapReduce技术的应用,使用java API。操作系统:Ubuntu24.04。 MapReduce概述 MapReduce概念 MapReduce是一个分布式运算程序的编程框架,核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序…

Centos9 离线安装 MYSQL8

centos 9 离线安装 mysql 8 参考教程 1. 官网下载mysql 下载地址 2. 将文件传输到Centos中解压 软件全部安装到了/opt中 在opt中新建mysql目录,解压到mysql目录中 tar -xvf mysql压缩文件 mysql[rootcentoshost mysql]# ls mysql-community-client-8.4.5-1.e…

helm的go模板语法学习

1、helm chart 1.0、什么是helm? 介绍:就是个包管理器。理解为java的maven、linux的yum就好。 安装方法也可参见官网: https://helm.sh/docs/intro/install 通过前面的演示我们知道,有了helm之后应用的安装、升级、查看、停止都…

display的一些学习记录

收集的SDM的log: 01-01 00:00:15.311 933 933 I SDM : Creating Display HW Composer HAL 01-01 00:00:15.311 933 933 I SDM : Scheduler priority settings completed 01-01 00:00:15.311 933 933 I SDM : Configuring RPC threadpool 0…

【Rust 精进之路之第2篇-初体验】安装、配置与 Hello Cargo:踏出 Rust 开发第一步

系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 **作者:**码觉客 发布日期: 2025-04-20 引言:磨刀不误砍柴工,装备先行! 在上一篇文章中,我们一起探索了 Rust 诞生的缘由&…

【深度学习】计算机视觉(17)——ViT理解与应用

文章目录 Embedding1 概念2 Q&A (1)3 Positional Encoding4 Q&A (2) ViT样例及Embedding可视化理解1 简化ViT练习2 CLS Token3 Embedding可视化4 多头注意力可视化 Embedding技术体系结构参考来源 在研究中对特征的编码和…

肖特基二极管详解:原理、作用、应用与选型要点

一、肖特基二极管的基本定义 肖特基二极管(Schottky Diode) 是一种基于金属-半导体结(肖特基势垒)的二极管,其核心特性是低正向压降(Vf≈0.3V)和超快开关速度。 结构特点:阳极采用金…

DeepSeek在数据仓库的10大应用场景

一、智能数据集成与清洗 多源数据整合:DeepSeek能够从多种数据源中提取、转换和加载数据,实现跨系统数据的高效整合。 数据清洗与标准化:通过智能算法自动识别并纠正数据中的错误、不一致性和缺失值,提升数据质量。 二、数据仓…

提示词构成要素对大语言模型跨模态内容生成质量的影响

提示词构成要素对大语言模型跨模态内容生成质量的影响 提示词清晰度、具象性与质量正相关 限定指向性要素优于引导指向性要素 大语言模型生成内容保真度偏差 以讯飞星火大模型为实验平台,选取100名具备技术素养的人员,从提示词分类、构成要素和实践原则归纳出7种提示词组…

BeautifulSoup 库的使用——python爬虫

文章目录 写在前面python 爬虫BeautifulSoup库是什么BeautifulSoup的安装解析器对比BeautifulSoup的使用BeautifulSoup 库中的4种类获取标签获取指定标签获取标签的的子标签获取标签的的父标签(上行遍历)获取标签的兄弟标签(平行遍历)获取注释根据条件查找标签根据CSS选择器查找…

关于MacOS使用Homebrew的详细介绍

Homebrew 是 macOS(和 Linux)上最流行的包管理工具(Package Manager),用于快速安装、更新和管理各种开发工具、命令行程序、开源软件等。它类似于: Ubuntu/Debian 的 aptCentOS/RHEL 的 yumWindows 的 Cho…

最新扣子空间实操指南

一、首先要先获取到内部测试的邀请码, 我们先打开扣子空间官网:https://space.coze.cn/ 输入邀请码后进入该页面: 它这里支持文件上传,扩展里面有很多插件,页支持MCP各种插件. 探索模式有两种,一种是ai自…

ubuntu22.04安装dukto

1.添加源 sudo add-apt-repository ppa:xuzhen666/dukto2.进行更新和安装 sudo apt update sudo apt install dukto3.报错 $ sudo apt install dukto 正在读取软件包列表... 完成 正在分析软件包的依赖关系树... 完成 正在读取状态信息... 完成 您也许需要…

Java编程基础(第四篇:字符串初次介绍)

前言 HelloWorld写的多了,语法熟悉一点了吧,其中有段代码还没介绍,它就是字符串 public class HelloWorld { public static void main(String[] args) { printBaby(); } static void printBaby() { System.out.print("baby"); } } …

安卓手机怎样配置数据加速

利用系统自带功能: 选择网络模式:进入手机 “设置”,找到 “网络” 或 “移动网络” 选项,点击 “高级设置”,选择合适的网络模式,如优先选择 4G 或 5G 网络,以获得更快的速度。开启网络加速功能…

Day3:个人中心页面布局前端项目uniapp壁纸实战

接下来我们来弄一下个人中心页面布局user.vue <template><view class"userLayout"><view class"userInfo"><view class"avatar"><image src"../../static/Kx.jpg" mode"aspectFill"></im…

线性回归之正则化(regularization)

文章目录 机器学习中的"防过拟合神器"&#xff1a;正则化全解析1. 正则化&#xff1a;不只是"规矩"那么简单1.1 鲁棒性案例说明 2. L1正则化&#xff1a;冷酷的特征选择器3. L2正则化&#xff1a;温柔的约束者4. L1 vs L2&#xff1a;兄弟间的较量5. 正则化…

mapbox基础,加载视频到地图

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️raster 栅格图层 api二、🍀加载视频到…