threading模块中Thread类是主要执行对象,可以有三种方法创建线程。1.给Thread实例传入一个函数。2.给Thread实力传如一个类实例。3.派生Thread子类创建一个子类的实例。
1.给Thread实例传入一个函数:
import threading
from time import sleep ,ctime
loops = [4,2]
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 = threading.Thread(target=loop,args=(i,loops[i]))
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
print 'all DONE at:', ctime()
if __name__ == '__main__':
main()
相对于上一个博客里thread模块没有了锁的直接应用,而是调用join方法进行阻塞,并且线程调用start之后开始执行,线程之间便于同步。
2.传入一个可调用类实例给Thread的方法实现线程:
import threading
from time import sleep ,ctime
loops = [4,2]
class ThreadFunc(object):
def __init__(self,func,args,name=''):
self.name = name
self.func = func
self.args = args
def __call__(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 = threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
print 'all DONE at:', ctime()
if __name__ == '__main__':
main()
3.派生Thread子类并实例化:
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[i]),loop.__name__)
threads.append(t)
for i in nloops:
threads[i].start()
for i in nloops:
threads[i].join()
print 'all DONE at:', ctime()
if __name__ == '__main__':
main()
总结:三种方法一般使用第三种方法就好,第一种封装性不好,第二种难于理解不利于代码阅读,我们可以把第三种方法普遍化一下
import threading
from time import ctime
class MyThread(threading.Thread):
def __init__(self,func,args,name=''):
threading.Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def getResult(self):
return self.res
def run(self):
print 'starting', self.name, 'at:', ctime()
self.res = self.func(*self.args)
print self.name, 'finished at:', ctime()
这段代码可以做为一个模块在程序里导入并使用它。
有时候为了有限的资源不被使用完,可以使用信号量设置最大的线程数量,当释放一次锁,信号量托盘获得它,即数目加一,若为0,不再执行代码。