每周一07:22,准时为你充电
一、使用场景
大家都知道python的多线程不是真正的多线程,但是对于io类型的任务,多线程还是能发挥作用的。那么多个线程之间是如何进行变量共享的呢,很多时候我们可以借助queue模块,方便。今天就做一个学习。
二、threading模块
Python的多线程还是主要使用标准库threading,该库提供了更高级别、功能更全面的线程管理。
该模块提供的主要方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
除了使用方法外,threading模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
Demo
# encoding: utf-8"""@python:v3.5.4@author:hutong@file:countthread.py@time:/07/06下午11:18"""importthreadingimporttimedefrun(n):print("task",n) time.sleep(5) #此时子线程停1sthreads_list=[]foriinrange(3):t=threading.Thread(target=run,args=("t-%s"%i,))threads_list.append(t)t.start()print(t.getName(),threading.active_count())#输出当前活跃的线程数formythreadinthreads_list: mythread.join() #等待所有的子线程都跑完print('all threads is done') #主线程
三、queue模块
Queue模块可以用来实现多线程间通讯,让各个线程共享数据,生产者把任务放到Queue中,供消费者(线程)去使用。在python3中,Queue模块被命名为queue。
Queue的对象有:
Queue.Queue(maxsize=0):创建大小为maxsize的FIFO(First In First Out)-Queue对象,如果maxsize不设置,这个队列将是无限的。
Queue.LifoQueue(maxsize=0): 创建先入后出的对象,即栈。Queue.PriorityQueue(maxsize=0):有优先级的队列。
Queue对象的方法有:
queue对象实现一个fifo队列(其他的还有lifo、priority队列,这里不再介绍)。queue只有qsize一个构造参数,用来指定队列容量,指定为0的时候代表容量无限。主要有以下成员函数:
Queue.qsize():返回消息队列的当前空间。返回的值不一定可靠。
Queue.empty():判断消息队列是否为空,返回True或False。同样不可靠。
Queue.full():类似上边,判断消息队列是否满
Queue.put(item, block=True, timeout=None):往消息队列中存放消息。block可以控制是否阻塞,timeout指定阻塞时候的等待时间。如果不阻塞或者超市,会引起一个full exception。
Queue.put_nowait(item):相当于put(item, False).
Queue.get(block=True, timeout=None):获取一个消息,其他同put。
以下两个函数用来判断消息对应的任务是否完成。
Queue.task_done():接受消息的线程通过调用这个函数来说明消息对应的任务已完成。
Queue.join():调用线程阻塞直到所有消息对应的任务已经完成。
消息队列实例中维护的有待完成任务变量。每接收到一个消息该值自增一次。每调用一次.task_done()可以使该值减1,当待完成任务值为0的时候,join函数才会返回。
四、threading和queue结合
大家可以参考如下的一个例子尝试完成任务。
demo
#encoding:utf-8"""@python:v3.5.4@author:hutong@file:threadingqueue.py@time:/7/6下午12:46"""importthreadingimporttimeimportqueue#下面来通过多线程来处理Queue里面的任务:defwork(q):whileTrue:ifq.empty():returnelse:t=q.get()print("当前线程sleep{}秒".format(t))time.sleep(t)defmain():q=queue.Queue()foriinrange(5):q.put(i)#往队列里生成消息thread_num=5threads=[]foriinrange(thread_num):t=threading.Thread(target=work,args=(q,))#args需要输出的是一个元组,如果只有一个参数,后面加,表示元组,否则会报错threads.append(t)foriinrange(thread_num):threads[i].start()foriinrange(thread_num):threads[i].join()if__name__=="__main__":start=time.time()main() print('耗时:',time.time()-start)
往队列里产生5条任务,启动5个线程去执行,由于是并行,所以总共耗时4s。如果更改单线程执行,那么就需要0+1+2+3+4=10s的时间。
小任务:大家可以尝试利用threading和queue完成一个上传文件到多台服务器。
觉得有帮助的,欢迎微信群转发哟。
大话性能网站(关注可以收藏更多好文章)
www.d
如果文章对你有帮助,
还请帮忙转发转发,谢谢。
问题交流/稿件投递
免费领取例子脚本和代码
免费入微信群交流
免费PMP考试咨询
扫一扫,加小T
专题推荐
●jmeter实时可视化图表化(高级)
●jmeter5.0源码在eclipse正确打开方式
●jmeter+Jenkins性能测试自动化搭建
●jmeter+Jenkins性能测试高级用法(番外篇)
●jmeter的websocket接口性能测试
●jmeter工作实战心法-高级需求(附福利)
●jmeter工作实战心法-必备技能(附赠小技巧)
●jmeter测试mongodb,必会,高级知识
●jmeter tcp脚本的核心知识点理解
●jmeter beanshell脚本如何编写2个例子
●jmeter如何一步步扩展自己的函数
●jmeter正则表达式应用
● 新人如何学习性能测试
● 性能测试利剑-微服务的分布式追踪
●python如何和java高效的交互