python threading获取线程函数返回值

最近需要用python写一个环境搭建工具,多线程并行对环境各个部分执行一些操作,并最终知道这些并行执行的操作是否都执行成功了,也就是判断这些操作函数的返回值是否为0。但是threading并没有显式的提供获取各个线程函数返回值的方法,只好自己动手,下面就介绍一下自己的实现方式。

一开始考虑到执行的操作可能有很多,而且后续会不断补充,因此先写了一个通用的多线程执行类,封装线程操作的基本方法,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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 class中写一个方法trace_func,作为直接的线程函数,这个trace_func中执行真正需要执行的函数,从而可以获取到该函数的返回值,设置给self.ret_flag。

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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()

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值