持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
多线程并发
单线程执行
Python的内置模块提供了两个线程模块:thread 和threading,thread是原生模块,threading 是扩展模块,在thread的基础上进行了封装及改进。所以只需要使用threading这个模块就能完成 并发的测试。先来介绍一下如何创建线程的语法。
变量=t =threadi.Thread(target=执行函数)
变量.start()
以一个单线程为例,实例代码:
1 import threading
2 def test():
3 print ("I am testing code!")
4 t=threading.Thread(target=test)
5 t.start()
代码说明:
1 导入threading 模块。
2~3自定义test0函数,并执行打印操作。
4用threading.Thread(方法创建一个线程,然后通过target参数把test0函数放到线程之中。
5启动线程执行线程中的函数test0)。
其实单线程执行的结果和单独执行某一个或者某一组函数的结果是一样的,区别只在于用线程的方式执行函数,而线程是可以同时多个一起执行的,函数是不可以同时执行的。
多线程执行
前面介绍了单个线程如何使用,多个线程只需要通过循环创建多个线程,并通过循环启动执 行就可以了。
实例代码:
1 import threading
2 def test():
3 print ("I am testing code!")
4 def thd():
5Threads= Threads=[]
6 for i in range(10):
7 t=threading.Thread(target=test)
8 Threads.append(t)
9 for t in Threads:
10 t.start()
11 if _name_=="_main_" main
12 thd()
代码说明:
4 自定义thd0函数用来创建并执行多个线程。
5 自定义一个空的threads数组,用来存放线程组。
6~8 通过循环10次来创建10个线程,并把每一次创建的线程t装到threads数组中。
9~10对10个线程进行循环启动。
12 执行thdO函数进行多线程的并发。
运行结果如图所示。
这样就通过10个线程执行了10次test(函数,但需要注意的是Python的并发并非绝对意义 上的同时处理,因为启动线程是通过循环启动的,还是有先后次序的,把test0函数改成打印当时的时间。
实例代码:
代码说明:
4 打印当前时间。
运行结果如图所示。
通过运行结果可见还是有细微的时间差异的,只是可以小的忽略不计,当然如果线程较多,就会扩大这种差异,所以实际使用中并不推荐建立太多线程来执行并发。那么如何才能优化呢?
举个例子,如果需要并发执行500次test(函数,启动500个线程会非常慢,也非常消耗资源,那就可以把500的并发拆成25个线程,每个线程再循环20次执行 test0函数,这样在启动下一个线程的时候,上一个线程已经在循环执行了,以此类推,当启动第25个线程的时候,可能已经执行了200次的test0函数,这样就可以大大减少并发的时间差异。下面通过对比来看执行时间的差异。
启动500个线程执行,实例代码就把循环次数改成500。运行结果如图
以算出一共花了0.16秒的时间执行500个“并发”。
然后我们改一下代码,实例代码:
1 import threading
2 from datetime import*
3 def test():
4 print (datetime.now())
5 def looptest():
6 for i in range (20):
7 test()
8 def thd():
9 Threads= hreads =[]
10 for i in range(25):
11 t=threading.Thread(target=looptest)
12 Threads.append(t)
13 for t in Threads:
14 t.start()
15 if name_ == "_ main_":
16 thd()
代码说明:
运行结果如图所示。
通过这2种方法的对比可看出时间上快了8倍,如果函数执行时间需要以秒计的话,这个差异就是显著的,所以如果有大并发量的测试,建议使用后者,这样才会更接近于同时“并发”。