多线程
多线程一直都感觉很神秘,一直有一种懂一点,但是又觉得什么都不懂的样子,只是知道它用处多多,灰常厉害,最近在做的几个项目当中由于处理的数据较多,所以也都引入了多线程来执行程序,但是由于多线程以前接触的不是很多,所以在应用方面还是有点小尴尬,总是出现一些各式各样的问题,所以想重新系统的学习一下线程的有关知识点;
线程有5种状态,状态转换的过程如下图所示:
threading
Python通过两个标准库thread和threading提供对线程的支持。thread提供了低级别的、原始的线程以及一个简单的锁。由于thread提供的线程功能不多,无法在主线程结束后继续运行,不提供条件变量等等原因,一般不使用thread模块,这里就不多介绍了,主要介绍一下threading模块
threading 模块提供的常用方法
1> 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
1 2 | threading.active_count() threading.activeCount() |
2>返回当前的线程变量
1 2 | threading.current_thread() threading.currentThread() |
3>返回当前正在运行的线程的列表。正在运行指线程启动后、结束前,不包括启动前和终止后的线程
1 | threading. enumerate () |
4>设置threading全局超时时间
1 | threading.TIMEOUT_MAX |
threading模块提供的类
1 | Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local |
Thread
是threading模块中最重要的类之一,可以使用它来创建线程,有两种方式来创建线程:
1、通过继承Thread类,重写它的run方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | import time import threading # 通过继承Thread创建类 class newThread(threading.Thread): def __init__( self , num): threading.Thread.__init__( self ) self .num = num def run( self ): time.sleep( 2 ) print ( "I am" , self .num) for i in range ( 10 ): t1 = newThread(i) t1.start() |
2、另一种是创建一个threading.Thread对象,在它的初始化函数(__init__)中将可调用对象作为参数传入
1 2 3 4 5 6 7 8 9 10 11 | import time import threading # 使用threading.Thread直接在线程中运行函数 def run(x): time.sleep( 2 ) print x for i in range ( 10 ): t1 = threading.Thread(target = run, args = (i,)) # 直接使用Thread附加函数,args为参数 t1.start() |
Lock
是threading模块中创建线程锁的类,我们创建一个该类对象,在线程函数执行前,“抢占”该锁,执行完成后,“释放”该锁,则我们确保了每次只有一个线程占有该锁。这时候对一个公共的对象进行操作,则不会发生线程不安全的现象了
1 2 3 4 5 6 7 8 9 | import threading #锁的使用 #创建锁 mutex = threading.Lock() #锁定,果设定了timeout,则在超时后通过返回值可以判断是否得到了锁,从而可以进行一些其他的处理 mutex.acquire([timeout]) #释放 mutex.release() |
当然,锁也可以作为上下文管理器使用(with Lock),可以不用重复的获取和释放锁
1 2 | with threading.Lock(): pass |
Rlock
与Lock类似,这两种琐的主要区别是:RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况(容易产生死锁现象)。注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐
1 2 3 4 5 6 7 8 9 10 11 12 13 | import threading lock = threading.Lock() #Lock对象 lock.acquire() lock.acquire() #产生了死琐。 lock.release() lock.release() import threading rLock = threading.RLock() #RLock对象 rLock.acquire() rLock.acquire() #在同一线程内,程序不会堵塞。 rLock.release() rLock.release() |
threading.Event
实现线程间通信
工作中遇到的线程实例
(创建的线程数在一定的范围内):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import time import threading as th def f1(i): time.sleep( 2 ) pass max_threadings = 10 for i in range ( 50 ): print '当前线程数量' , len (th. enumerate ()) while True : if len (th. enumerate ()) < max_threadings: try : newthread = th.Thread(target = f1, args = (i,)) break except : continue else : pass newthread.start() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现