Python 多任务编程:进程、线程与协程全面解析

目录

一、多任务基础:并发与并行

1. 什么是多任务

2. 两种表现形式

二、进程:操作系统资源分配的最小单位

1. 进程的概念

2. 多进程实现多任务

2.1 基础示例:边听音乐边敲代码

2.2 带参数的进程任务

2.3 进程编号与应用注意点

2.3.1 进程编号的作用

2.3.2 关键注意点

三、线程:程序执行的最小单位

1. 线程的概念

2. 多线程实现多任务

3. 线程的核心特性

四、进程与线程的对比

五、协程:用户态的轻量级线程

1. 协程的概念

2. 核心优势

3. 基于asyncio实现协程

4. 协程的适用场景与注意事项

六、总结:如何选择多任务方案


在日常开发中,我们经常会遇到需要同时处理多个任务的场景,比如网盘同时下载多个文件、程序一边播放音乐一边执行计算。这些都离不开多任务编程技术。本文将基于 Python,从多任务的基础概念出发,详细讲解进程、线程与协程三种实现方式,帮助你轻松掌握多任务编程的核心逻辑。

一、多任务基础:并发与并行

1. 什么是多任务

多任务指在同一时间内执行多个任务,比如电脑同时运行微信、浏览器和代码编辑器。其核心价值是充分利用 CPU 资源,提升程序执行效率

2. 两种表现形式

多任务的实现分为 “并发” 和 “并行”,二者的核心区别在于是否 “真正同时执行”:

(1)并发:单核 CPU 场景下,操作系统轮流让多个任务交替执行(如任务 1 执行 0.01 秒→切换到任务 2 执行 0.01 秒)。由于 CPU 速度极快,表面上看起来任务在同时运行。适用场景:任务数量>CPU 核心数

(2)并行:多核 CPU 场景下,每个核心分别执行一个任务,多个任务真正同时进行。适用场景:任务数量≤CPU 核心数

二、进程:操作系统资源分配的最小单位

1. 进程的概念

进程(Process)是操作系统进行资源分配和调度的基本单位,一个正在运行的程序就是一个进程(如打开的微信、Chrome 浏览器)。一个程序运行后至少会创建一个主进程

2. 多进程实现多任务

通过 Python 的multiprocessing模块,我们可以创建子进程,让多个任务并行执行。

核心步骤

(1)导入multiprocessing模块;
(2)用multiprocessing.Process()创建进程对象,指定目标任务(函数名);
(3)调用start()方法启动进程。

2.1 基础示例:边听音乐边敲代码

import multiprocessing
import time# 任务1:听音乐
def music():for i in range(3):print("听音乐...")time.sleep(0.2)# 任务2:敲代码
def coding():for i in range(3):print("敲代码...")time.sleep(0.2)if __name__ == '__main__':# 创建进程对象music_process = multiprocessing.Process(target=music)coding_process = multiprocessing.Process(target=coding)# 启动进程music_process.start()coding_process.start()

2.2 带参数的进程任务

通过args(元组)或kwargs(字典)给任务传递参数:

if __name__ == '__main__':# 元组传参(注意逗号)music_process = multiprocessing.Process(target=music, args=(3,))# 字典传参coding_process = multiprocessing.Process(target=coding, kwargs={'count': 3})music_process.start()coding_process.start()

2.3 进程编号与应用注意点

2.3.1 进程编号的作用

每个进程都有唯一编号(PID),用于区分主进程和子进程,方便进程管理。通过os模块获取:

(1)os.getpid():获取当前进程编号;

(2)os.getppid():获取父进程编号(创建当前进程的进程)

2.3.2 关键注意点

(1)进程间不共享全局变量:子进程会拷贝主进程的资源,修改子进程的全局变量不会影响主进程;

(2)主进程与子进程的结束顺序:默认主进程会等待所有子进程执行完再结束。若需主进程结束时子进程也终止,可:

  • 设置守护进程:process.daemon = True;
  • 手动终止子进程:process.terminate()。

三、线程:程序执行的最小单位

1. 线程的概念

线程(Thread)是进程内的执行单元,共享进程的所有资源(如内存、文件句柄)。一个进程默认有一个主线程,可创建多个子线程,就像 “一个 QQ 打开两个聊天窗口”,既实现多任务又节省资源。

2. 多线程实现多任务

通过threading模块实现,步骤与多进程类似,且资源开销更低、启动速度更快。

基础示例

import threading
import timedef music():for i in range(3):print("听音乐...")time.sleep(0.2)def coding():for i in range(3):print("敲代码...")time.sleep(0.2)if __name__ == '__main__':# 创建线程对象music_thread = threading.Thread(target=music)coding_thread = threading.Thread(target=coding)# 启动线程music_thread.start()coding_thread.start()

3. 线程的核心特性

  • 共享全局变量:同一进程内的线程共享全局变量(如列表、字典),但需注意 “线程安全”(需用锁避免数据竞争);
  • 执行顺序无序:线程的执行由 CPU 调度决定,无法保证顺序;
  • 守护线程:设置thread.daemon = True,主线程结束时子线程自动终止。

四、进程与线程的对比

特性进程(Process)线程(Thread)
定义资源分配最小单位程序执行最小单位
资源开销高(独立内存、资源)低(共享进程资源)
启动速度
全局变量共享不共享(需 IPC 通信)共享(需锁保证安全)
适用场景CPU 密集型任务(如计算、数据分析)I/O 密集型任务(如网络请求、文件读写)
模块multiprocessingthreading

五、协程:用户态的轻量级线程

1. 协程的概念

协程(Coroutine)是用户态的轻量级线程,通过 “协作式调度” 实现并发 —— 无需操作系统介入,仅需保存寄存器上下文,切换效率极高。

2. 核心优势

  • 无锁机制:避免多线程的同步开销;
  • 高并发:单线程内可处理数千个 I/O 密集型任务;
  • 代码简洁:用async/await语法,以同步风格写异步逻辑。

3. 基于asyncio实现协程

asyncio是 Python 官方协程库,核心是 “事件循环”(管理协程的执行)。

基础示例

import asyncio# 定义协程函数(用async修饰)
async def my_coroutine():print("Start")# 非阻塞等待(替代time.sleep,不阻塞事件循环)await asyncio.sleep(1)print("End")# 启动事件循环
asyncio.run(my_coroutine())

并发执行多个协程

用asyncio.create_task()创建任务,asyncio.gather()并发执行:

async def task(name, delay):await asyncio.sleep(delay)print(f"{name} completed")async def main():# 创建任务列表tasks = [asyncio.create_task(task("A", 2)),asyncio.create_task(task("B", 1))]# 并发执行await asyncio.gather(*tasks)asyncio.run(main())
# 输出:B completed → A completed(按完成时间排序)

4. 协程的适用场景与注意事项

  • 适用场景:I/O 密集型任务(如网络爬虫、API 调用),结合aiohttp(异步 HTTP 库)可大幅提升效率;
  • 注意事项

(1)协程内禁用time.sleep()等同步操作,需用asyncio.sleep();

(2)需 Python 3.7+,推荐用asyncio.run()管理事件循环。

(3)不适合 CPU 密集型任务(需结合多进程);

六、总结:如何选择多任务方案

  1. CPU 密集型任务(如计算、矩阵运算):用多进程(绕过 Python GIL 锁,利用多核 CPU);
  2. I/O 密集型任务(如网络请求、文件读写):优先用协程(效率最高、资源开销最低),其次用多线程;
  3. 简单多任务场景:若无需多核利用,用多线程(实现简单、通信方便)。

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

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

相关文章

ADSL技术

<摘要> ADSL&#xff08;非对称数字用户线路&#xff09;是一种利用传统电话线实现宽带上网的技术。其核心原理是频率分割&#xff1a;将一根电话线的频带划分为语音、上行数据&#xff08;慢&#xff09;和下行数据&#xff08;快&#xff09;三个独立频道&#xff0c;从…

信号衰减中的分贝到底是怎么回事

问题&#xff1a;在一个低通滤波中&#xff0c;经常会看到一个值-3dB&#xff08;-3分贝&#xff09;&#xff0c;到底是个什么含义&#xff1f; 今天我就来粗浅的讲解这个问题。 在低通滤波器中&#xff0c;我们说的 “截止频率”&#xff08;或叫 - 3dB 点&#xff09;&…

工具分享--IP与域名提取工具2.0

基于原版的基础上新增了一个功能点:IP-A段过滤&#xff0c;可以快速把内网192、170、10或者其它你想要过滤掉的IP-A段轻松去掉&#xff0c;提高你的干活效率&#xff01;&#xff01;&#xff01; 界面样式预览&#xff1a;<!DOCTYPE html> <html lang"zh-CN&quo…

如何通过日志先行原则保障数据持久化:Redis AOF 和 MySQL redo log 的对比

在分布式系统或数据库管理系统中&#xff0c;日志先行原则&#xff08;Write-Ahead Logging&#xff0c;WAL&#xff09; 是确保数据一致性、持久性和恢复能力的重要机制。通过 WAL&#xff0c;系统能够在发生故障时恢复数据&#xff0c;保证数据的可靠性。在这篇博客中&#x…

临床研究三千问——临床研究体系的3个维度(8)

在上周的文章中&#xff0c;我们共同探讨了1345-10战策的“临床研究的起点——如何提出一个犀利的临床与科学问题”。问题固然是灵魂&#xff0c;但若没有坚实的骨架与血肉&#xff0c;灵魂便无所依归。今天&#xff0c;我们将深入“1345-10战策”中的“3”&#xff0c;即支撑起…

AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年9月7日第172弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀4-5个和值&#xff0c;可以做到100-300注左右。(1)定位…

万字详解网络编程之socket

一&#xff0c;socket简介1.什么是socketsocket通常也称作"套接字"&#xff0c;⽤于描述IP地址和端⼝&#xff0c;是⼀个通信链的句柄&#xff0c;应用程序通常通过"套接字"向⽹络发出请求或者应答⽹络请求。⽹络通信就是两个进程间的通信&#xff0c;这两…

维度跃迁:当万物皆成电路,智能将从“拥有”变为“存在”

我们习以为常的电子世界&#xff0c;其本质是一个由电路构成的精密宇宙。而一场从二维到三维的终极变革&#xff0c;正在悄然酝酿&#xff0c;它将彻底颠覆我们创造和交互的方式。一、电子世界的本质&#xff1a;一切都是电路 在深入未来之前&#xff0c;我们首先要理解当下。电…

大语言模型预训练数据采集与清洗技术实践:从语料到知识库的全流程优化

大语言模型(LLM)的性能上限由 “数据质量 数据规模 数据多样性” 共同决定 —— 预训练阶段的海量语料决定模型的泛化能力与语言理解基础,而知识库数据则决定模型的知识准确性与领域专业性。当前 LLM 落地面临的核心痛点之一,便是 “数据脏、处理难、知识杂”:预训练语料…

模拟音频采集设备的制作

模拟音频程序与设备的制作 需要设备 esp32s3 pcm1808 pcm5102(非必须) 程序界面 程序代码 代码链接

Java Modbus通信实战(四):Modbus通信测试与故障排查

在工业现场&#xff0c;设备通信系统就像工厂的神经网络&#xff0c;连接着各种传感器、控制器和执行器。当你搭建好这套系统后&#xff0c;最关键的一步就是全面测试&#xff0c;确保每个环节都能正常工作。 就像汽车出厂前要经过严格的路试一样&#xff0c;Modbus RTU通信系统…

少儿编程C++快速教程之——1. 基础语法和输入输出

1. 欢迎来到C编程世界&#xff01; 1.1 什么是编程&#xff1f; 编程就像是给计算机写一份详细的"说明书"&#xff0c;告诉它该做什么、怎么做。C是一种强大的编程语言&#xff0c;可以用来创建游戏、应用程序和各种有趣的软件&#xff01; 1.2 第一个C程序&#xff…

arma::imat22

arma::imat22 是 Armadillo C 线性代数库中定义的一个固定大小的 2x2 有符号整数矩阵类型。它主要用于处理小型、维度在编译时已知的整数矩阵&#xff0c;因其在栈上分配内存&#xff0c;故通常比动态矩阵有更高的效率。 下面是一个汇总了 arma::imat22 主要特性的表格&#xf…

狗都能看懂的HunYuan3D 1.0详解

HunYuan3D 1.0 HunYuan3D 1.0是2024年9月发布的一篇论文。虽然站在现在的时间节点&#xff0c;HunYuan3D系列已经出到2.5了&#xff0c;但是1.0版本的改进思路&#xff0c;和它trick集成的做法&#xff0c;还是很值得学习的。由于文章用到了很多技术&#xff0c;由于篇幅有限&a…

踏脚迈入奇幻乐园

每天早上上班的路上都会经过一个小花园。它被夹在丁字路口的拐角&#xff0c;面积不大&#xff0c;匆匆而过的行人都不会注意到它。但如果顺着几个不起眼的入口走进去&#xff0c;里面却是别有洞天。清早的街道还没有车水马龙的喧哗&#xff0c;花园里静悄悄的。各式各样的花草…

内存越界引发线程函数调用堆栈回溯异常以及INT 3软中断实战分析案例分享

目录 1、问题说明 2、导出dump文件时只是遇到了INT 3软中断&#xff0c;并没有发生异常崩溃 3、函数中发生了栈内存越界&#xff0c;导致线程的栈回溯出异常&#xff0c;堆栈中只显示一行函数调用记录 3.1、处理Json数据时产生了异常 3.2、函数中发生栈内存越界&#xff0…

LeetCode 240: 搜索二维矩阵 II - 算法详解(秒懂系列

文章目录LeetCode 240: 搜索二维矩阵 II - 算法详解题目描述Java解决方案算法思路核心理念为什么选择右上角&#xff1f;可视化演示过程示例1&#xff1a;查找 target 5示例2&#xff1a;查找 target 20 (不存在)算法分析时间复杂度空间复杂度算法优势关键要点扩展思考LeetCo…

洛谷 B4071 [GESP202412 五级] 武器强化

思考难度低&#xff0c;但是代码难度相对较高的题&#xff0c;故做个记录。首先&#xff0c;题目说了要花费最少的钱&#xff0c;所以我们每次拿最便宜的材料给武器1思想&#xff1a;每次都拿最便宜的材料然后考虑一下这个思想是否正确&#xff0c;找一下反例&#xff0c;每次拿…

SQL工具30年演进史:从Oracle到Navicat、DBeaver,再到Web原生SQLynx

目录 一、1990s&#xff1a;厂商自带的数据库工具时代 二、2000s&#xff1a;Navicat等商业数据库管理工具崛起 三、2010s&#xff1a;DBeaver等开源SQL工具兴起 四、2020s&#xff1a;SQLynx&#xff0c;Web原生数据库管理工具 五、SQL工具30年时间线对比 六、总结&…

C语言制作扫雷游戏(拓展版赋源码)

目录 引言&#xff1a; 三个新功能实现 1.可以选择难度或自定义 实现难点解析 代码实现&#xff08;附源码&#xff09; 扫雷.c game.h game.c 2.对选择位置进行标记或取消标记 一.框架 我们先理一下思路 如何构造框架 二.取消标记函数 三.标记函数 四.加入清屏&#xff0c;进…