Python threading获取线程函数返回值的方法
本文介绍如何在Python中使用threading模块获取多线程函数的返回值。通过封装MyThread类,利用trace_func包装目标函数,捕获执行结果并汇总至ret_flag。该方法解决了标准threading未直接提供返回值获取接口的问题,适用于需要并行执行并验证所有操作成功状态的场景。
threading模块用于提供线程相关的操作支持,线程是应用程序中工作的最小单元。当前Python版本的多线程库尚未实现优先级、线程组等功能,且线程无法被停止、暂停、恢复或中断。
threading模块提供的类包括:
Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。
threading模块提供的常用方法有:
threading.currentThread():返回当前的线程变量。
threading.enumerate():返回一个包含正在运行的线程的列表。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount():返回正在运行的线程数量,其结果与len(threading.enumerate())相同。
threading模块提供的常量包括:
threading.TIMEOUT_MAX,用于设置threading全局超时时间。
接下来进入正文部分。
近期开发环境搭建工具时,需要使用Python进行多线程并行操作,以执行环境各部分的配置任务,并最终确认这些并行操作是否全部成功,即判断各操作函数的返回值是否为0。由于threading模块未显式提供获取线程函数返回值的方法,因此需要自行实现,下文将介绍具体的实现方式。
考虑到执行的操作可能数量众多且后续会不断补充,首先编写了一个通用的多线程执行类,用于封装线程操作的基本方法,代码如下:
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参数,该列表中的每个元素是一个字典,包含func和args两个键。func代表要执行的函数引用,args为函数的参数。核心方法是start方法,它负责多线程执行每个func,并阻塞直到所有线程执行结束。关键在于如何正确设置self.ret_flag,以判断所有线程函数是否均返回0。
实现思路是在MyThread类中定义一个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 ret:1 func2 ret:2 func3 ret:100 all thread ret : 103
总结。
以上介绍了Python使用threading获取线程函数返回值的实现方法,希望对大家有所帮助。如有任何疑问,请留言,小编会及时回复。感谢大家对本站的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













