start
函数用于开始某个线程
定义两个函数,第一个函数耗时2秒,第二个函数耗时4秒,两个函数同时运行。观察运行结果
import threading
import time
#函数1
def doFirstThing(url):
print("First Thing Star")
time.sleep(2)
print('First Thing Finished')
#函数2
def doSecondThing(url):
print("Second Thing Star")
time.sleep(4)
print('Second Thing Finished')
if __name__ == "__main__":
#传入threading
thread1 = threading.Thread(target=doFirstThing,args=("",))
thread2 = threading.Thread(target=doSecondThing, args=("",))
start_time = time.time()
thread1.start()
thread2.start()
end = time.time()
print('time:%s'%(end-start_time))
运行结果
First Thing Star
Second Thing Star
time:0.0
First Thing Finished
Second Thing Finished
运行结果很奇怪,因为 计时应该在完成之后而不是完成之前,我们debug来看一下。
debug可以看到这里实际上有三个线程,一个主线程MainThread
和两个子线程Thread-7
,Thread-6
,程序在主线程结束之后并不会停止,而是会等到子线程也运行完之后才停止。而这三个线程又是独立运行的,所以时间输出在线程结束之前了。
如果我们想让子线程会随着主线程结束而结束,就需要使用setDaemon
函数设置守护线程。当线程设置了这个参数就会随着主线程的结束一起结束。
import threading
import time
def doFirstThing(url):
print("First Thing Star")
time.sleep(2)
print('First Thing Finished')
def doSecondThing(url):
print("Second Thing Star")
time.sleep(4)
print('Second Thing Finished')
if __name__ == "__main__":
thread1 = threading.Thread(target=doFirstThing,args=("",))
thread2 = threading.Thread(target=doSecondThing, args=("",))
start_time = time.time()
thread1.setDaemon(True)
thread2.setDaemon(True)
thread1.start()
thread2.start()
end = time.time()
print('time:%s'%(end-start_time))
函数运行结果,可以看到没有 finished字样输出,因为随着主线程结束子线程也被强制结束掉了
First Thing Star
Second Thing Star
time:0.0
Process finished with exit code 0
但是这个结果并不是我们想看到的,我们想看到的是两个子线程同时运行,并且time约等于4,类似于两个函数并行的运行然后节约掉了2秒钟。这个时候就需要使用join
函数了。使用了这个程序的主线程会被当前未运行完的线程阻塞掉,直到所有线程运行完毕。
import threading
import time
def doFirstThing(url):
print("First Thing Star")
time.sleep(2)
print('First Thing Finished')
def doSecondThing(url):
print("Second Thing Star")
time.sleep(4)
print('Second Thing Finished')
if __name__ == "__main__":
thread1 = threading.Thread(target=doFirstThing,args=("",))
thread2 = threading.Thread(target=doSecondThing, args=("",))
start_time = time.time()
thread1.start()
thread2.start()
thread1.join()
thread2.join()
end = time.time()
print('time:%s'%(end-start_time))
这就是我们想看到的结果,运行时间4秒左右。相比起阻塞式编程,使用多线程节约了两秒。
First Thing Star
Second Thing Star
First Thing Finished
Second Thing Finished
time:4.002061605453491
Process finished with exit code 0
通过thread类继承并且重载run
方法实际上可以达到和之前的写法一样的效果,但是对于一些较为复杂的逻辑,通过类完成多线程更容易维护。
import threading
import time
class doFirstThing(threading.Thread):
def __init__(self,name):
super().__init__(name=name)
def run(self):
print("First Thing Star")
time.sleep(2)
print('First Thing Finished')
class doSecondThing(threading.Thread):
def __init__(self, name):
super().__init__(name=name)
def run(self):
print("Second Thing Star")
time.sleep(4)
print('Second Thing Finished')
if __name__=="__main__":
thread1 = doFirstThing('FirstThing')
thread2 = doSecondThing('SecondThing')
start_time = time.time()
thread1.start()
thread2.start()
thread1.join()
thread2.join()
end = time.time()
print('time:%s'%(end-start_time))
相同的结果
First Thing Star
Second Thing Star
First Thing Finished
Second Thing Finished
time:4.002086877822876
Process finished with exit code 0