• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

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

python 水墨上仙 1320次浏览

可以异步执行多个函数,然后获取多个函数的返回值,对其返回值进行分析判断是否所有函数都执行成功
转自:http://www.cnblogs.com/qualitysong/archive/2011/05/27/2060246.html

import threading
class 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&nbspclass中写一个方法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_num
 
def func2(ret_num):
    print "func2 ret:%d" % ret_num
    return ret_num
 
def func3():
    print "func3 ret:100"
    return 100
 
mt = 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

最后的输出结果
func1&nbspret:1
func2&nbspret:2
func3&nbspret:100
all&nbspthread&nbspret&nbsp:&nbsp103


喜欢 (1)
加载中……