Python多线程Threading、子线程与守护线程实例详解如下:
线程与进程:
- 线程:线程是被系统独立调度和分派的基本单位,它自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
- 多线程:在单个程序中同时运行多个线程完成不同的工作,称为多线程。对于IO密集型的程序来说,多线程可以利用读IO的时间去做其他事;而对于CPU密集型的程序来说,多线程的效率就不是很高了。
线程Threading:
- Python中多线程需要使用threading模块。
- 线程的创建与运行:
直接调用threading的Thread类:
线程的创建:线程对象=thread.Thread(target=函数名,args=(参数))。由于args是一个元组,单个参数时要加“,”
线程的启动:线程对象.start(),调用start(),那么线程对象会自动去调用thread.Thread中的run()
让主线程等待其余线程结束:线程对象.join(),加了join之后,相当于阻塞了主线程,主线程只有当join的线程结束后才会向下执行
import threading,time def run(n): time.sleep(1) print("task ",n) t1=threading.Thread(target=run,args=("t1",))t2 = threading.Thread(target=run,args=("t2",)) start_time=time.time()#开始时间t1.start()t2.start()##因为是独立线程,如果想要主线程等待其他线程运行完毕,需要使用joint1.join()t2.join()spend_time=time.time()-start_timeprint(spend_time)##1.0多,说明是并行的结果- 继承threading的Thread类:
继承threading的Thread类的类要主要做两件事:
如果不做自定义变量的初始化,那么可以直接使用继承的父类的__init__(),如果需要做自定义变量的初始化,则需要先调用父类的__init__()【否则需要自己填写线程初始化相关的参数】
重写run,虽然继承了父类的run,但实际上如果不重写,那么我们继承threading的Thread类又有什么意义呢?为什么不直接调用threading的Thread类
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__()#调用父类的__init__() self.name=name def run(self):#重写方法,按自己的要求去写 time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")t2=MyTread("t2")start_time=time.time()t1.start()t2.start()###主线程等待其余线程结束t1.join()t2.join()print(time.time()-start_time)#结果是1.0多,证明是并行的子线程:
守护线程:
- 守护线程是起到辅助功能的,就好像魔法师放禁咒总要骑士保护一样【魔法师只需要关系自己的任务,保护他的任务交给守护者】
- 而守护线程与主线程的关系呢,就好像备胎跟女神,去买东西的话,备胎要一直在外面等女神【守护线程运行结束就狗带,但不影响主进程结束,由主线程决定运行时间】,女神不需要等待备胎【主线程结束,守护线程也要结束,不管自身任务是否完成】
- 与join的区别:join是阻塞等待,守护线程是并行的等待
- 设置守护线程:线程对象.setDaemon(True)【注意!!!!!设置守护线程必须要在start()前面,不然会报错】
- 下面的代码显示了主线程并不会等待其守护线程结束:
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__() self.name=name def run(self): print("守护线程已经启动",self.name) time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")t1.setDaemon(True)t2=MyTread("t2")t2.setDaemon(True)start_time=time.time()#开始时间t1.start()t2.start() spend_time=time.time()-start_timeprint(spend_time)##0.0多,而且三个线程都执行完毕了,说明这个是并行的等待- 让主线程sleep一下,显示一下如果主线程要等待守护线程,那么是并行的等待:
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__() self.name=name def run(self): print("守护线程已经启动",self.name) time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1")t1.setDaemon(True)t2=MyTread("t2")t2.setDaemon(True)start_time=time.time()#开始时间t1.start()t2.start()time.sleep(2)spend_time=time.time()-start_timeprint(spend_time)##2.0多,而且三个线程都执行完毕了,说明这个是并行的等待