- 简单的案例
- damon用法
为了对多线程有一个直观的了解,现举一个简单的案例
>>> def printN(n,name=None):
... for i in range(n):
... print(f"{name}:{i}")
...
>>> th1 = Thread(target=printN,args=[3,'th1'])
>>> th2 = Thread(target=printN,args=[3,'th2'])
>>> def test():
... th1.start()
... th2.start()
...
>>> test()
th1:0
th1:1
th2:0
th1:2
th2:1
th2:2
>>> th1.start() #线程只能start一次
RuntimeError: threads can only be started once
>>>
其中,Thread作为线程类的构造函数,其输入的target为将要执行的函数,args则为这个函数中将要输入的参数。所以th1代表执行printN(3,'th1'),th1代表执行printN(3,'th2')。
start函数相当于线程的启动函数。
由于在命令行中操作,所以放我们将这两个线程的测试函数放到test中,在调用test的时候发现,尽管th1先start,th2后start,但二者的确是交错执行的,说明th1和th2走的是不同的线程。
damon用法为了理解damon的用法,最好创建一个文件test.py,内容如下。
#test.py
from time import time as Now
from threading import Thread
def printNow(name):
while True:
print(name,Now())
if __name__=='__main__':
th1 = Thread(target=printNow,args=['th1'])
th2 = Thread(target=printNow,args=['th2'])
th1.start()
th2.start()
这时候如果在命令行中执行python test.py,那么将迎来th1和th2这两个线程的无休止地输出。而面对二者疯狂地输出,我们唯一的办法就是关闭命令行。
这个时候使用Ctrl+C是没有用的,因为Ctrl+C只能关闭python test.py这个线程,但对th1和th2是无能为力的。
为了摆脱这种尴尬的局面,只需启用daemon,将两个线程改为
th1 = Thread(target=printNow,args=['th1'],daemon=True) th2 = Thread(target=printNow,args=['th2'],daemon=True)
这个时候,不出意外地报了错,由于在开启th2.start()之后,主线程便已经结束了,而th1和th2又把daemon设为了True,所以不得不杀死主线程的这两个子线程,所以报错。
如果在th2.start()后面再加上一个死循环
from time import sleep while(1):sleep(1)
那么由于父线程无法终止,所以子线程也将一直输出,但这时可通过Ctrl+C来终止父线程,进而终止子线程。



