Python多线程异步获得多函数调用的返回值,python多线程,import threa


import threadingclass MyThread(object):    def __init__(self, func_list=None):    #所有线程函数的返回值汇总,如果最后为0,说明全部成功        self.ret_flag = 0        self.func_list = func_list        self.threads = []    def set_thread_func_list(self, func_list):        """        @note: func_list是一个list,每个元素是一个dict,有func和args两个参数        """        self.func_list = func_list    def start(self):        """        @note: 启动多线程执行,并阻塞到结束        """        self.threads = []        self.ret_flag = 0        for func_dict in self.func_list:            if func_dict["args"]:                t = threading.Thread(target=func_dict["func"], args=func_dict["args"])            else:                t = threading.Thread(target=func_dict["func"])            self.threads.append(t)        for thread_obj in self.threads:            thread_obj.start()        for thread_obj in self.threads:            thread_obj.join()    def ret_value(self):        """        @note: 所有线程函数的返回值之和,如果为0那么表示所有函数执行成功        """        return self.ret_flag

MyThread类会接受一个func_list参数,每个元素是一个dict,有func和args两个key,func是真正要执行的函数引用,args是函数的参数。其中最主要的方法是start方法,会多线程执行每个func,然后一直等到所有线程都执行结束后退出。接下来的关键就是如何对self.ret_flag设置正确的值,以判断所有的线程函数是否都返回0了。

我的实现是,在MyThread class;中写一个方法trace_func,作为直接的线程函数,这个trace_func中执行真正需要执行的函数,从而可以获取到该函数的返回值,设置给self.ret_flag。

这个trace_func的第一参数是要执行的func引用,后面是这个func的参数,具体代码如下:

def trace_func(self, func, *args, **kwargs):    """    @note:替代profile_func,新的跟踪线程返回值的函数,对真正执行的线程函数包一次函数,以获取返回值    """    ret = func(*args, **kwargs)    self.ret_flag += ret

这样就需要修改start方法中Thread函数的设置,代码如下:

def start(self):    """    @note: 启动多线程执行,并阻塞到结束    """    self.threads = []    self.ret_flag = 0    for func_dict in self.func_list:        if func_dict["args"]:            new_arg_list = []            new_arg_list.append(func_dict["func"])            for arg in func_dict["args"]:                new_arg_list.append(arg)            new_arg_tuple = tuple(new_arg_list)            t = threading.Thread(target=self.trace_func, args=new_arg_tuple)        else:            t = threading.Thread(target=self.trace_func, args=(func_dict["func"],))        self.threads.append(t)    for thread_obj in self.threads:        thread_obj.start()    for thread_obj in self.threads:        thread_obj.join()

这样能够成功获得返回值了,实验:

def func1(ret_num):    print "func1 ret:%d" % ret_num    return ret_numdef func2(ret_num):    print "func2 ret:%d" % ret_num    return ret_numdef func3():    print "func3 ret:100"    return 100mt = MyThread()g_func_list = []g_func_list.append({"func":func1,"args":(1,)})g_func_list.append({"func":func2,"args":(2,)})g_func_list.append({"func":func3,"args":None})mt.set_thread_func_list(g_func_list)mt.start()print "all thread ret : %d" % mt.ret_flag

评论关闭