定时器:
我们来举一个例子,比如定时炸弹,设定一个时间后炸弹爆炸,Python定时器也就是设定规定时间后,线程在启动。
import threading#导入模块
class Time(threading.Thread):#创建类
def __init__(self):#初始化
super(Time,self).__init__()#父类初始化
print("定时器启动:")#打印
print(threading.current_thread())#打印当前线程
t2 = threading.Timer(3,function=Time)#设置定时器
t2.start()#开启线程
if __name__ == '__main__':#主函数
t1 = threading.Timer(3,function=Time)#创建定时器
t1.start()#开启线程
输出结果:
线程每启动一个都不是一样的,而且是每个3秒启动一个线程
队列:方法请看代码中的详细注释
import queue # 导入模块
Que = queue.Queue(maxsize=3) # 创建队列对象,设置存入最大数量为3
Que.put(0) # 存入0
Que.put(1) # 存入1
print(f"队列是否存满:{Que.full()}") # 查看是否存满,否则返回false
Que.put(2) # 存入数据
print(f"队列是否存满:{Que.full()}") # 查看数据是否存满
print(f"可获取数据数量为:{Que.qsize()}") # 查看可获取数据的数量
print(f"队列是否为空:{Que.empty()}") # 查看队列是否为空
print(Que.get()) # 获取队列数据
print(Que.get()) # 获取队列数据
print(f"队列是否为空:{Que.empty()}") # 查看队列是否为空
print(Que.get()) # 获取队列数据
print(f"队列是否为空:{Que.empty()}") # 查看队列是否为空
print(f"可获取数据数量为:{Que.qsize()}") # 查看可获取数据数量
输出结果:
线程池:
线程池可以提高性能,防止启动大量线程而导致系统变慢,可以更简单的创建线程,适用于突发的适用于大量线程,而线程存在时间短的场景。
"""线程池由concurrent.futures下的ThreadPoolExecutot提供,
submit(fn, *args,**kwargs)将函数fn提交给线程池,后面是参数
map(fn,*iterables,timeout=None,chunksize=1)启动多线程,
让函数fn分别使用后面的可迭代参数shutdown(wait=True)关闭线程池
"""
"""使用submit()函数提交后会返回一个Future对象
cancel()可以取消该线程,如果线程正在运行,不可取消,返回False,否则取消线程,并返回True
cancelled()返回线程是否被取消
running()返回线程是否正在运行
done()返回线程是否完成,包括取消和正常完成
result(timeout=None)获取该线程的返回结果,会阻塞线程,
timeout是阻塞时间add_done_callback(fn)线程结束后执行fn函数
"""
样例:
import time
from concurrent.futures import ThreadPoolExecutor#导入模块
def run(number):#创建函数
print(f"线程{number}启动")#打印
# time.sleep(1)#设置延迟看的更清楚
if __name__ == '__main__':#主函数
pool = ThreadPoolExecutor(max_workers=2)#设置线程池最大容量为2
f1 = pool.submit(run, 1)#以下启动三个线程
f2 = pool.submit(run, 2)
f3 = pool.submit(run, 3)
print(f1.done())#以下判断线程是否完成
print(f2.done())
print(f3.done())
print("程序结束")#打印
输出结果:
因为线程池设置的最大数量是2,可以看见线程1和2已经启动完成,打印true,而线程3还未开始,打印false,当线程1和2完成之后,线程3才启动。