当前位置: 首页 > news >正文

Python多线程:让程序 “多线作战” 的秘密武器

Python多线程:让程序 “多线作战” 的秘密武器

图片

一、什么是多线程?

在日常生活中,我们可以一边听音乐一边浏览新闻,这就是 “多任务处理”。在Python编程里,多线程同样允许程序同时执行多个任务,从而提升程序的执行效率和响应速度 。不过,Python中的多线程由于全局解释器锁(GIL)的存在,在CPU密集型任务中表现受限,但在I/O密集型任务(如网络请求、文件读写)中却能大放异彩。

二、Python多线程核心函数及案例

1. threading.Thread()

功能:用于创建线程对象,是多线程编程的基础。通过传入target参数指定线程要执行的函数,args参数传递函数所需的参数。

案例:同时打印两条不同的消息,模拟多任务执行。

import threading
import timedef print_message(message):for _ in range(3):print(message)time.sleep(1)thread1 = threading.Thread(target=print_message, args=("线程1正在工作",))
thread2 = threading.Thread(target=print_message, args=("线程2正在工作",))thread1.start()
thread2.start()thread1.join()
thread2.join()
print('主程序执行结束')#程序执行后打印如下:
线程1正在工作
线程2正在工作
线程1正在工作
线程2正在工作
线程1正在工作
线程2正在工作
主程序执行结束#多次执行后可能如下:
线程1正在工作
线程2正在工作
线程1正在工作线程2正在工作线程1正在工作
线程2正在工作
主程序执行结束

解析:定义print_message函数用于打印消息,创建thread1和thread2两个线程对象,分别传入不同的消息作为参数。调用start()方法启动子线程,线程开始并行执行对应的函数;join()方法会阻塞主线程(主程序执行时就算一个主线程),等待子线程执行完毕。

以上结果因为添加了join函数,主程序最后的print打印消息是在最后才执行,但是子线程打印消息还是出现了跟预期不一致的地方。如果注释掉上面的join方法,多次执行结果可能如下:会发现主程序的print日志混在了子线程print日志中间,原因是因为主线程和子线程同时操作print函数导致的。

#结果1
线程1正在工作
线程2正在工作
主程序执行结束
线程1正在工作线程2正在工作线程2正在工作
线程1正在工作#结果2
线程1正在工作
线程2正在工作
主程序执行结束
线程1正在工作
线程2正在工作
线程1正在工作线程2正在工作

2. threading.Lock()

功能:创建锁对象,用于解决多线程中共享资源的竞争问题,避免数据不一致。当一个线程获取锁后,其他线程必须等待,直到该线程释放锁。

案例:接着上面的案例,我们通过对print打印加锁,保证同一时间只有一个线程操作print打印。

通过threading.Lock()定义锁对象,通过lock.acquire()加锁,lock.release()释放锁。

import threading
import timelock = threading.Lock()
def print_message(message):for _ in range(3):lock.acquire()print(message)lock.release()time.sleep(1)thread1 = threading.Thread(target=print_message, args=("线程1正在工作",))
thread2 = threading.Thread(target=print_message, args=("线程2正在工作",))thread1.start()
thread2.start()thread1.join()
thread2.join()
print('主程序执行结束')#程序执行后,结果如下:不会出现打印错乱的情况
线程1正在工作
线程2正在工作
线程1正在工作
线程2正在工作
线程1正在工作
线程2正在工作
主程序执行结束

3. threading.Timer()

功能:创建一个定时器线程,在指定的延迟时间后执行函数。

案例:延迟3秒后打印提示信息。

import threadingdef delayed_function(name):print(f"3秒已到,{name}开始执行任务!")
#定时三秒
timer = threading.Timer(3, delayed_function,args=('线程1',))timer.start()

解析:threading.Timer(3, delayed_function)表示创建一个延迟 3 秒后执行delayed_function的定时器线程,调用start()启动定时器。

4. threading.current_thread()

功能:返回当前正在执行的线程对象。

案例:在函数中查看当前执行的线程。

import threading
def check_thread():current = threading.current_thread()print(f"当前执行的线程是: {current.name}")
#子线程执行
thread = threading.Thread(target=check_thread)
thread.start()
#主程序执行
check_thread()#结果:
当前执行的线程是: Thread-1 (check_thread)
当前执行的线程是: MainThread

解析:check_thread函数中使用threading.current_thread()获取当前线程对象,并打印线程名称,既在子线程中调用,也在主线程中调用,对比输出结果。

5. threading.active_count()

功能:返回当前活动的线程数量(包括主线程)。

案例:统计程序中活动线程数。


import threading
import timedef thread_task():time.sleep(2)threads = []
for _ in range(3):t = threading.Thread(target=thread_task)threads.append(t)t.start()
print(f"启动子线程后,活动线程数: {threading.active_count()}")for t in threads:t.join()print(f"子线程执行完毕后,活动线程数: {threading.active_count()}")#执行结果
启动子线程后,活动线程数: 4
子线程执行完毕后,活动线程数: 1

解析:创建3个子线程并启动,使用threading.active_count()分别在启动子线程后和子线程执行完毕后统计活动线程数量,子线程结束后主线程还在,所以最后还统计到1个。

6.threading.local()

功能:threading.local用于创建线程局部变量,每个线程都有自己独立的变量副本,线程之间的变量互不干扰。

案例:模拟多线程处理用户请求,每个线程记录自己处理的请求编号。

import threading
# 创建threading.local对象
local_data = threading.local()def process_request(request_id):# 为每个线程设置独立的请求编号local_data.request_id = request_idprint(f"线程 {threading.current_thread().name} 正在处理请求 {local_data.request_id}")# 在同一线程的其他函数中使用该变量additional_processing()def additional_processing():print(f"线程 {threading.current_thread().name} 继续处理请求 {local_data.request_id}")threads = []
for i in range(3):t = threading.Thread(target=process_request, args=(i,))threads.append(t)t.start()
for t in threads:t.join()
#结果:
线程 Thread-1 (process_request) 正在处理请求 0
线程 Thread-1 (process_request) 继续处理请求 0
线程 Thread-2 (process_request) 正在处理请求 1
线程 Thread-2 (process_request) 继续处理请求 1
线程 Thread-3 (process_request) 正在处理请求 2
线程 Thread-3 (process_request) 继续处理请求 2

解析:首先创建threading.local对象local_data。在process_request函数中,为每个线程设置独立的request_id属性,不同线程的local_data.request_id相互独立。additional_processing函数可以在同一线程内访问该属性,体现了线程局部变量在同一线程内共享、不同线程间隔离的特性。

三、实用案例详解

1. 多线程处理网络请求

场景:需要从多个网站获取数据,如果顺序执行,会浪费大量等待响应的时间。使用多线程可以同时发起多个请求,提高效率。


import requests
import threading
def fetch_data(url):try:response = requests.get(url)print(f"从 {url} 获取数据成功,状态码: {response.status_code}")except requests.RequestException as e:print(f"从 {url} 获取数据失败: {e}")urls = ["https://www.example1.com","https://www.example2.com","https://www.example3.com"
]threads = []
for url in urls:t = threading.Thread(target=fetch_data, args=(url,))threads.append(t)t.start()
for t in threads:t.join()

解析:定义fetch_data函数用于发送网络请求并处理响应,将多个 URL 放入列表,为每个 URL 创建一个线程发起请求,实现多任务并行处理网络请求。

2. 多线程实现文件读写

场景:同时读取多个文件并进行处理,或者同时向多个文件写入数据。

import threading
def read_file(file_path):try:with open(file_path, 'r') as file:content = file.read()print(f"读取 {file_path} 内容: {content}")except FileNotFoundError:print(f"{file_path} 不存在")file_paths = ["file1.txt", "file2.txt", "file3.txt"]threads = []for path in file_paths:t = threading.Thread(target=read_file, args=(path,))threads.append(t)t.start()for t in threads:t.join()

解析:read_file函数负责读取文件内容,通过多线程为每个文件路径创建线程,同时读取多个文件,提升文件处理效率。

4、总结

Python多线程是提升程序效率的有力工具,尤其在I/O密集型任务中优势显著。通过掌握threading模块的核心函数,灵活运用多线程技术,让程序实现 “多线作战”。但也要牢记多线程的局限性,不是线程越多越好,同时避免死锁,线程安全问题,最后选择合适的并发方案,才能发挥出 Python的最大潜力!

http://www.dtcms.com/a/407480.html

相关文章:

  • 黟县方坑岭影视基地三剧连拍开机 《生死制暴》影视赋能乡村振兴
  • 微信网站打不开海南搜索引擎优化
  • 国产化(银河麒麟_海光CPU)消息中间件选型及安装
  • 宁波品牌网站推广优化公司章丘营销型网站设计公司
  • p6spy 打印完整sql
  • 【ARM】MDK-Functions界面设置
  • 沈阳市建设局网站首页网站的运行与维护
  • 昌宁县住房和城乡建设网站订阅号做流量 那些电影如何链接网站
  • 【LVS入门宝典】LVS调度算法轮询(RR)深度解析:从原理到实战的公平调度之道
  • udhcpc, udhcpd由 BusyBox编译出来就好
  • 前端 CORS 深度解析
  • HT81696 概述
  • PMP-项目管理-PMBOK第六版_中文版:引论
  • 上海网站建站建设自己做的网站在百度怎么发布
  • SpringBoot+QQ 邮箱邮件开发指南:环境配置、功能实现、异常处理一站式搞定
  • Linux 数据库 Mysql8 主从复制
  • 做网站的图片房产国内免费推广网站
  • 建设网站需要分析什么条件云南软件开发项目管理
  • OpenHands+cpolar:AI编程助手的远程调试新方案
  • 从 0 到 1 掌握 ESP32 RMT(新手友好版)
  • 做设计什么网站可以兼职网站管理与建设总结
  • 少样本学习学习论文分享:多模态性帮助单模态性
  • 深入MySQL底层2-SQL优化与数据库运维管理
  • 设计站网页制作的公司选时代创信
  • 国外服装网站石岩做网站哪家好
  • 超越单边控制:介绍新一代对话智能体评测基准τ2-Bench
  • Scala • basis
  • vi设计公司深圳企业网站排名怎么优化
  • 深度学习视角下的图像分类技术体系总结
  • mysql数据库最新版下载,安装