main()
执行结果:
starting at: Sun Jan 8 18:07:28 2017
start loop 0 at: Sun Jan 8 18:07:28 2017
start loop 1 at: Sun Jan 8 18:07:28 2017
loop 1 done at: Sun Jan 8 18:07:30 2017
loop 0 done at: Sun Jan 8 18:07:32 2017
all DONE at: Sun Jan 8 18:07:32 2017
当实例化Thread对象时,把函数(target)和参数(args)传进去,然后得到返回的Thread实例。实例化Thread(调用Thread())时,新线程不会立即执行。这是一个非常有用的同步功能,尤其是当你并不希望线程立即开始执行时。
当所有线程都分配完成之后,通过调用每个线程的start()方法让它们开始执行,而不是在这之前执行。相比于管理一组锁(分配,获取,释放,检查锁状态等)而言,这里只需要为每个线程调用join()方法即可。join()方法将等待线程结束,或者在提供了超时时间的情况下,达到超时时间,使用join()方法要比等待锁释放的无限循环更加清晰。
对于join()方法而言,其另一个重要方面是其实它根本不需要调用,一旦线程启动,它们就会一直执行,直到给定的函数完成后退出。如果主线程还有其他事情要去做,而不是等待这些线程完成(例如其他处理或者等待新的客户端请求),就可以不调用join()。join()方法只有在你需要等待线程完成的时候才是有用的。 派生Thread的子类,并创建子类的实例
下面的这个例子要调用Thread()的子类,当创建线程时使用子类要相对更容易阅读。
子类化的Thread
本例中将对Thread子类化,而不是直接对其实例化。这将使我们在定制线程对象时拥有更多的灵活性,也能够简化线程的调用过程。
# -*- coding:utf-8 -*-
import threading
from time import sleep,ctime
loops = (4,2)
class MyThread(threading.Thread):
def __init__(self,func,args,name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def run(self):
self.func(*self.args)
def loop(nloop,nsec):
print('start loop',nloop,'at:',ctime())
sleep(nsec)
print('loop',nloop,'done at:',ctime())
def main():
print('starting at:',ctime())
threads = []
nloops = range(len(loops))
for i in nloops:
t = MyThread(loop,(i,loops),loop.__name__)
threads.append(t)
for i in nloops:
threads.start()
for i in nloops:
threads.join()
print('all DONE at:',ctime())
if __name__ == '__main__':
main()
执行结果:
starting at: Sun Jan 8 18:38:21 2017
start loop 0 at: Sun Jan 8 18:38:21 2017
start loop 1 at: Sun Jan 8 18:38:21 2017
loop 1 done at: Sun Jan 8 18:38:23 2017
loop 0 done at: Sun Jan 8 18:38:25 2017
all DONE at: Sun Jan 8 18:38:25 2017
注意:MyThread子类的构造函数必须先调用其基类的构造函数,重写run()方法
现在,对MyThrea类进行修改,增加一些调试信息的输出,并将其存储为一个名为myThread的独立模块。除了简单地调用函数外,还将把结果保存在实例属性self.res中,并创建一个新的方法getResult()来获取这个值。
import threading
from time import ctime