环境(python3.6)
threading模块中所有可用对象的列表
threading模块其他函数
threading模块的Thread类
Thread类
创建Thread的实例,传给它一个函数(代码1)
#!/usr/bin/env python
# encoding: utf-8
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:
#把函数(target)和参数(args)传进去
t = threading.Thread(target=loop,args=(i,loops[i])) #(产生一个线程)
print('线程{0}已实例化)'.format(i))
threads.append(t)
for i in nloops:
print('线程 {0} 启动'.format(i))
threads[i].start() #开始运行
print('线程 {0} 启动结束'.format(i))
for i in nloops:
threads[i].join() #等待线程结束的方法
print('线程 {0} 已结束'.format(i))
print('all DONE at :',ctime())
if __name__=='__main__':
main()
运行结果
创建Thread实例,传给它一个可调用的类实例(代码2)
import threading
from time import sleep,ctime
loops=[4,2]
class ThreadFunc(object):
def __init__(self,func,args,name = ''):
self.func = func#传进来函数
self.args = args#传进来参数
self.name = name#传进来函数名字
def __call__(self):
#可以传递初始化函数参数的特殊方法
print('call要被使用了')
self.func(*self.args)
print('call已被使用完,产生了{0}'.format((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:
#把函数(target)和参数(args)传进去
t = threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))
print('线程{0}已实例化)'.format(i))
threads.append(t)
for i in nloops:
print('线程 {0} 启动'.format(i))
threads[i].start() #开始运行
print('线程 {0} 启动结束'.format(i))
for i in nloops:
threads[i].join() #等待线程结束的方法
print('线程 {0} 已结束'.format(i))
print('all DONE at :',ctime())
if __name__=='__main__':
main()
结果说明
在产生类的实例的时候已经在call的特殊方法中传递了fun函数需要的参数,所有Thread调用的时候就不需要再次传递,可直接调用了。
派生Thread的子类,并创建子类的实例(代码3)
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.func = func#传进来函数
self.args = args#传进来参数
self.name = name#传进来函数名字
def run(self):
#可以传递初始化函数参数的特殊方法
#print('run要被使用了')
self.func(*self.args)
#print('run已被使用完,产生了{0}'.format((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:
#把函数(target)和参数(args)传进去
t = MyThread(loop,(i,loops[i]),loop.__name__)
print('线程{0}已实例化'.format(i))
threads.append(t)
for i in nloops:
print('线程 {0} 启动'.format(i))
threads[i].start() #开始运行
print('线程 {0} 启动结束'.format(i))
for i in nloops:
threads[i].join() #等待线程结束的方法
print('线程 {0} 已结束'.format(i))
print('all DONE at :',ctime())
if __name__=='__main__':
main()
运行结果
join()方法说明
对于join()方法而言,其另一个重要方面是其实它根本不需要调用。一旦线程启动,它就会一直执行,直到给定的函数完成后退出。如果主线程还有其他事情要去做,而不是等待这些线程完成(例如其他处理或者等待新的客户端请求),就可以不调用join()。join()方法只有在你需要等待线程完成的时候才是有用的。
代码2和代码3的比较
当比较2和3这两代码时,注意其中的几个变化:1)MyThread子类的构造函数必须先调用其基类的构造函数;2)代码2中的特殊方法cell()在这个子类中必须写成run(),其他名字不行。