Python recipe(17):Future
代码何在?
Example Source Code [http://www.cnblogs.com/tomsheep/]
''' Created on 2010-5-28 @author: lk ''' import threading,copy class FutureTask: def __init__(self, func, *params): self.__done = 0 self.__result = None self.__C = threading.Condition()#for result self.__T = threading.Thread(target = self.Wrapper, args = (func, params)) self.__T.setName("FutureThread") self.__T.start() def __call__(self): self.__C.acquire() while not self.__done: self.__C.wait() self.__C.release() result = copy.deepcopy(self.__result) return result def isDone(self): return self.__done def Wrapper(self,func,params): self.__C.acquire() self.__result = func(*params) self.__done = 1 self.__C.notify() self.__C.release() if __name__ == '__main__': pass
以上代码改写自Python Cookbook 6-5
概述:
熟悉Java的童鞋都知道Java中有一个很好用的接口叫Future,表示异步计算的结果。他的有一个实现FutureTask,同时实现了Runnable接口。可以接受一个Callable做构造参数,异步执行该Callable的任务,保存结果。这里用python模拟了FutureTask.
代码说明:
1. 疑问一:本段代码在构造函数里直接开启一个线程,这在Java里被视为不安全操作,因为可能提前publish了一个未构造好的对象;Python的机制我不是太懂,但个人觉得应该也存在类似问题。更好的做法可能是完全模拟Java,让FutureTask继承Thread,在run方法中让__T开始执行。
2.疑问二:在Wrapper中先notify在放锁,会不会出现一个时间差,让等待线程在两者之间再次陷入wait,而之后没有机会被notify?后来想到wait方法应该是先要acquire这个锁的,所以如果没被放,会暂时block住。所以不会再次wait。
3. 疑问三:为什么在__call__中用deepcopy返回result,而不是用一个大锁锁住整个方法,最后返回__result本身?我认为有两点考虑,第一,这样会影响throughput,第二,如果result不是immutable对象,直接返回本身相当于一个不安全的发布(publish),使用它的客户代码需要额外的同步操作。