threading模块
线程
- 线程被称为轻量级进程(Lightweight Process,LWP),是cpu调度的基本单位
- 组成:线程ID、当前指令指针(PC)、寄存器集合、堆栈组成
- 在单个程序中同时运行多个线程完成不同的工作,称为多线程。
threading功能
threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。
■ threading模块提供的常用类:
- Thread:创建线程
- Lock/RLock:互斥锁
threading——Thread
Thread构造方法
• 构造方法: Thread(group=None, target=None, name=None, args=(), kwargs={})
• group: 线程组,目前还没有实现,库引用中提示必须是None;
• target: 要执行的方法;
• name: 线程名;
• args/kwargs: 要传入方法的参数
###计算主线程的运行时间
import requests
import time
import functools
import threading
def runtime(func):#func要接收一个callable对象
print("this is run time")
@functools.wraps(func) # 保留传递进来函数的元数据,将他的元数据赋值给inner
def inner(*args,**kwargs):#所以把功能写在inner里就行
start=time.time()
result=func(*args,**kwargs)#要将原函数的返回值保存起来
end=time.time()
print(f"函数执行花了{end-start}s")
return result
return inner
def get_content(url):
text=requests.get(url).content
time.sleep(0.5)
print("get content")
@runtime
def main():
for i in range(5):
# get_content("https://www.baidu.com")
#创建多线程,有六个线程---一个主线程五个子线程
#target--->指定传入的方法名字,要做什么
#args--->指定方法需要传入的参数(元组类型)
t=threading.Thread(target=get_content,args=("https://www.baidu.com",))
t.start()#启动线程-->自动的执行run方法
main()
输出:
this is run time
函数执行花了0.001995086669921875s#统计的是main线程创建子线程的时间
get content
get content
get content
get content
get content
###若需要计算子线程的运行时间呢?
#引入t.join()
#**t.join([timeout])**: 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。
import requests
import time
import functools
import threading
def runtime(func):#func要接收一个callable对象
print("this is run time")
@functools.wraps(func) # 保留传递进来函数的元数据,将他的元数据赋值给inner
def inner(*args,**kwargs):#所以把功能写在inner里就行
start=time.time()
result=func(*args,**kwargs)#要将原函数的返回值保存起来
end=time.time()
print(f"函数执行花了{end-start}s")
return result
return inner
def get_content(url):
text=requests.get(url).content
time.sleep(0.5)
print("get content")
@runtime
def main():
t_list=[]
for i in range(5):
# get_content("https://www.baidu.com")
#创建多线程
#target--->指定传入的方法名字,要做什么
#args--->指定方法需要传入的参数(元组类型)
t=threading.Thread(target=get_content,args=("https://www.baidu.com",))
t_list.append(t)
t.start()#启动线程-->自动的执行run方法
# t.join()#若是join放在此处多线程将没有意义
for t in t_list:
#阻塞当前环境(谁执行join代码,谁就是当前环境)上下文,直到t线程执行完成(主线程去做)
t.join()
#只有当t的线程执行完成才会执行
print("ending..............")
main()
输出:
this is run time
get content
get content
get contentget contentget content
ending..............
函数执行花了0.657221794128418s
Thread实例方法
• t.name:获取或设置线程的名称
• t.getName()/setName(name): 获取/设置线程名。
• t.is_alive()、t.isAlive():判断线程是否为激活状态。返回线程是否在运行。正在运行指启动后、终止前。
• t.ident :获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才有效,否则它只返回None
• t.run() :线程被cpu调度后自动执行线程对象的run方法
• t.start(): 线程准备就绪,等待CPU调度,start会自动调用t.run()
• t.join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。
t.setDaemon(bool): 设置是后台线程(默认前台线程(False))。(在start之前设置)
-
Python3.10中,set.Daemon(aTrue)这种写法已经弃用了,正确的写法是.daemon=True
举例:
t=threading.Thread(target=h)
t.daemon=True
t.start() -
如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止
-
如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
• t.isDaemon:判断是否为后台线程
#设置是后台线程
#t.daemon=True
import requests
import time
import functools
import threading
def runtime(func):#func要接收一个callable对象
print("this is run time")
@functools.wraps(func) # 保留传递进来函数的元数据,将他的元数据赋值给inner
def inner(*args,**kwargs):#所以把功能写在inner里就行
start=time.time()
result=func(*args,**kwargs)#要将原函数的返回值保存起来
end=time.time()
print(f"函数执行花了{end-start}s")
return result
return inner
def get_content(url):
text=requests.get(url).content
time.sleep(0.5)
print("get content")
@runtime
def main():
t_list=[]
for i in range(5):
# get_content("https://www.baidu.com")
#创建多线程
#target--->指定传入的方法名字,要做什么
#args--->指定方法需要传入的参数(元组类型)
t=threading.Thread(target=get_content,args=("https://www.baidu.com",))
t_list.append(t)
#默认为前台线程,主线程执行完了,等子线程执行完再退出
#t.setDaemon=True#设置后台线程,主线程退出子线程就立马退出
t.daemon=True
t.start()#启动线程-->自动的执行run方法
# t.join()#若是join放在此处多线程将没有意义
# for t in t_list:
# #阻塞当前环境(谁执行join代码,谁就是当前环境)上下文,直到t线程执行完成(主线程去做)
# t.join()
#只有当t的线程执行完成才会执行
print("ending..............")
main()
输出:
this is run time
ending..............
函数执行花了0.0029897689819335938s
自定义线程类
import threading
class MYThread(threading.Thread):#继承threading.Thread
def __init__(self,num):
super(MYThread,self).__init__()
self.num=num
def run(self):#重写run方法
print(f"running on numbers:{self.num}")
t1=MYThread(1)
t2=MYThread(2)
t1.start()
t2.start()
输出:
running on numbers:1
running on numbers:2
Process finished with exit code 0