简介
是一个人搬砖快呢?还是两个人、三个人、四个人?很显然我们人多情况下是比较快的,但是不是越多越快?理论上是这样的,但是在实际的应用中,我们要考虑场景的具体情况,比如说工作的场地就这么一点,你非要那么多人参与进来进行工作,那么也就只能出现人挤人的现象,并不能加快搬砖的速度。
现实中就存在可以多个人同时做一个事件,来促进事件的完成时间,也就是节约时间。在我们编程中有这样的概念叫做多线程,它可以让我们的分成几份,让他们同时进行工作。我们的Python也是有这样的一个模块,能够为我们节约时间。
Python拥有_thread和threading模块(Python 3)都可以用于实现多线程的操作,这里直接讲threading模块,为什么推荐threading模块?因为该模块比较适合我们新手=比较简单。
threading模块基础知识
导入方式:import threading
创建线程:threading.Thread(target=fun1,args=(a,))
target后面书写要执行多线程的函数名称,args括号里面填写要传递的参数用元组表示(*特别的是当仅传入一个参数时,需要在第一个参数后面添加逗号*。理由是元组中只包含一个元素时,需要在元素后面添加逗号),不传递参数的时候可以省略args。
开始线程:使用start()函数,表达如下:
thread=threading.Thread(target=fun1,args=(a,)
thread.start()
其他方法介绍:
is_alive() 方法查询线程是否还在运行,正在运行返回True,否则返回False
join() 方法提供线程阻塞手段,join() 方法会一直等待对应线程的结束,但可以通过参数赋值,等待规定的时间。使用join(timeout=None)传递timeout属性,默认为空。timeout 是一个浮点参数,单位是秒。如可以传递join(1.0)表达,当1秒内线程还没结束就会跳过这个锁定执行接下来的内容。
OK,我们多线程基础知识就先介绍到这里,更多细节自行进行学习。接下来,我们直接进入应用场景。
应用场景
让我们先看看多线程和正常运行两次函数的效果比较:
通过结果我们可以看出,我们普通情况运行两次,它是会根据函数执行时间进行叠加的,然而我们的多线程是在同一秒里面执行了两次,果然是起到了节约时间的效果。那从这边的执行情况这少了一秒你们可能感觉不是很明显,但是当我们这个函数需要执行100次甚至更多的时候,你就会发现你节约了特别多的时间。
给大家一个场景大家可以去实现一下,我们知道可以通过ping去探测主机是否存活,那么我们如何去了解整个C段里面有多少存活的主机呢?可以多线程编程的方式去实现ping 192.168.0.1/24 一整个C段。这个场景就很显然一个一个去ping会耗费掉很多的时间。
*小提示:*
使用模块subprocess可以实现执行命令的操作
如:
from subprocess import PIPE,run
ip='192.168.0.1'
check_ping=run(['ping','-n','2',ip],stdin=PIPE,stdout=PIPE,shell=True)
result = check_ping.stdout.decode('gbk')
print(result)
ping 一下192.168.0.2,结果如下
通过比对ping通和ping不通的结果,得到通过结果里面是否存在TTL就可以判断是否ping通
结果展示
以下是使用100个线程去跑的一个结果,耗费的时间是39秒多
然后是使用300个线程跑的结果:是19秒多
然后,我调整到500个线程去跑一下,结果是20秒多
那么发现了什么问题,没错,就是我们的C段是1-255,也就是需要ping 255次,这个任务最多只能分成255个线程去做,多了也不能加快任务的完成。当然,在实际的应用中,我们不用打印那么多结果,该场景我们只需要打印哪些ip是ping得通的就行了,这边是为了效果的展示,也可以通过这个结果查看我们程序是否正确ping了那么多个ip。