Python recipe(17):Future

代码何在?

div css xhtml xml Example Source Code 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),使用它的客户代码需要额外的同步操作。

posted on 2010-05-29 00:05  tomsheep  阅读(378)  评论(0编辑  收藏  举报

导航