- 创建一个Thread的实例,传给它一个可调用的类对象
在练习18.5的例18.5时,照着例子抄错了,如下:
#!/usr/bin/env python import threading from time import ctime,sleep class ThreadFuc(object): def __init__(self,func,args,name=''): self.name=name self.func=func self.args=args def __call__(self): #apply(self.func,self.args) self.res=self.func(*self.args) def loop(nloop,nsec): print("%s start at %s"%(nloop,ctime())) sleep(nsec) print("%s ended at %s"%(nloop,ctime())) def main(): nsect=[2,4] threads=[] nloop=range(len(nsect)) print("thread start at %s"%ctime()) for i in nloop: t=threading.Thread(target=ThreadFuc(loop,(i,nsect[i]),loop.__name__)) threads.append(t) for i in nloop: threads[i].start() for i in nloop: threads[i].join() print("all done at %s"%ctime()) if __name__=='__main__': main()
第21行应该为nsect[i],却抄例子写错为loop[i],结果运行后就报错如下:
Traceback (most recent call last): File "mtsleep4.py", line 28, in <module> main() File "mtsleep4.py", line 20, in main t=threading.Thread(target=ThreadFuc(loop,(i,loop[i]),loop.__name__)) TypeError: 'function' object is unsubscriptable
即调用loop函数时找不到对应参数所以报错。此句即创建了一个ThreadFuc实例,比如a,此实例是可调用的,即运行a.call()。apply(self.func,self.args)在python1.6及以上版本中又可写为self.res=self.func(*self.args)。换句话说,即此实例执行self.res=loop(nsect[i])。这里loop为global值,如果将loop函数算入此类型的方法中,会报global name 'loop' is not defined。最终的运行结果如下:
thread start at Tue Jul 7 19:03:19 2015 0 start at Tue Jul 7 19:03:19 2015 1 start at Tue Jul 7 19:03:19 2015 0 ended at Tue Jul 7 19:03:21 2015 1 ended at Tue Jul 7 19:03:23 2015 all done at Tue Jul 7 19:03:23 2015
2. 从Thread派生一个类,创建这个类的一个实例myThread.py
#!/usr/bin/env python import threading from time import ctime,sleep 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): apply(self.func,self.args) #self.res=self.func(*self.args) def loop(nloop,nsec): print("%s start at %s"%(nloop,ctime())) sleep(nsec) print("%s ended at %s"%(nloop,ctime())) def add(num): print("This is %s thread"%num) def main(): nsect=[2,4] threads=[] nloop=range(len(nsect)) print("thread start at %s"%ctime()) for i in nloop: t=MyThread(loop,(i,nsect[i]),loop.__name__) threads.append(t) for i in nloop: threads[i].start() for i in nloop: threads[i].join() print("all done at %s"%ctime()) if __name__=='__main__': main()3. 利用步骤2的方式来完成斐波那契,阶乘和累加:
#!/usr/local/env python from time import ctime,sleep from myThread import MyThread def fib(n): sleep(0.0005) if (n==0): return 0 elif n==1: return 1 else: return(fib(n-2)+fib(n-1)) def sum(n): sleep(0.1) if(n<=2): return 1 else: return(sum(n-1)+n) def mult(n): sleep(0.0001) if(n<2): return 1; else: return (n*mult(n-1)) def main(): fiction=[mult,sum,fib] threads=[] num=12 nloop=range(len(fiction)) print("*****Single thread******") for i in nloop: print("%s thread starts at %s"%(fiction[i].__name__,ctime())) print(fiction[i](num)) print("%s thread ends at %s"%(fiction[i].__name__,ctime())) print("*****Multi threads******") for i in nloop: t=MyThread(fiction[i],(num,),fiction[i].__name__) threads.append(t) for i in nloop: threads[i].start() for i in nloop: threads[i].join() print(threads[i].getResult()) print("Done!") if __name__=='__main__': main()注意创建线程时,第二个参数是一个序列,而不是一个int值,这是apply函数所要求的。 4. 利用线程来实现生产者消费者:
#!/usr/local/env python from myThread import MyThread from Queue import Queue from time import ctime,sleep from random import randint def writeQ(queue): if not queue.full(): print("starting writer at %s"%ctime()) queue.put("x") print("producing obj for Q...size now is %s"%queue.qsize()) def writer(queue,num): sleep(0.1) if num>0: for i in range(num): writeQ(queue) def readeQ(queue): if not queue.empty(): print("starting condutor at %s"%queue.get()) print("consumed obj for Q...size now is %s"%queue.qsize()) def reader(queue,num): sleep(0.6) if num> 0: for i in range(num): readeQ(queue) def main(): q=Queue(10) threads=[] function=[writer,reader] nloop=range(len(function)) print("***********Start production/conduction**************") for i in nloop: t=MyThread(function[i],(q,randint(2,4)),function[i].__name__) threads.append(t) for i in nloop: threads[i].start() for i in nloop: threads[i].join() print("*******************Done***************************") if __name__=='__main__': main()