线程
线程被称为轻量级进程(Lightweight Process,LWP),是cpu调度的基本单位
组成:线程ID、当前指令指针(PC)、寄存器集合、堆栈组成
在单个程序中同时运行多个线程完成不同的工作,称为多线程。
python中提供了thread和threading模块对线程进行操作,其中thread模块是比较底层的模块,threading模块对thread做了一些包装,使用更方便。
threading模块常用方法
- threading.active_count() 返回当前处于active状态的Thread对象的个数
- threading.current_thread() 返回当前Thread对象
- threading.get_ident() 返回当前线程的线程标识
- threading.enumerate() 返回当前处于active状态的所有Thread对象列表
- threading.main_thread() 返回主线程对象,启动python解释器的线程对象
- threading.stack_size() 返回创建线程时使用的栈的大小,如果指定 size参数,则用来指定后续创建的线程使用的 栈大小,size必须是0(标识使用系统默认值) 或大于32K的正整数
threading模块提供了Thread、Lock、RLock、Condition、Event、Timer和Semaphore等类支持多线程。
###计算主线程的运行时间
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
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
自定义线程类
在使用threading模块时,也可以定义一个新的类class,继承threading.Thread,然后重写run()。
threading.Thread类中的run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法。创建自己的线程实例后,通过Thread类的start方法,可以启动该线程。
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
标签:get,python,content,threading,线程,模块,time,start
From: https://blog.51cto.com/u_12760266/6346555