python使用threading获取线程函数返回值的实现方法


Posted in Python onNovember 15, 2017

threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。python当前版本的多线程库没有实现优先级、线程组,线程也不能被停止、暂停、恢复、中断。

threading模块提供的类: 

Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。

threading 模块提供的常用方法:

threading.currentThread(): 返回当前的线程变量。

threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。

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参数,每个元素是一个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_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获取线程函数返回值的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python随机生成一个6位的验证码代码分享
Mar 24 Python
Python更新数据库脚本两种方法及对比介绍
Jul 27 Python
python扫描proxy并获取可用代理ip的实例
Aug 07 Python
python 处理dataframe中的时间字段方法
Apr 10 Python
Python判断两个list是否是父子集关系的实例
May 04 Python
解决python "No module named pip" 的问题
Oct 13 Python
python+pyqt5编写md5生成器
Mar 18 Python
Python concurrent.futures模块使用实例
Dec 24 Python
利用keras使用神经网络预测销量操作
Jul 07 Python
Python如何使用ElementTree解析xml
Oct 12 Python
python使用requests库爬取拉勾网招聘信息的实现
Nov 20 Python
Python 求向量的余弦值操作
Mar 04 Python
python enumerate函数的使用方法总结
Nov 15 #Python
Python set常用操作函数集锦
Nov 15 #Python
python机器学习库常用汇总
Nov 15 #Python
python爬虫系列Selenium定向爬取虎扑篮球图片详解
Nov 15 #Python
给你选择Python语言实现机器学习算法的三大理由
Nov 15 #Python
Python数据结构之顺序表的实现代码示例
Nov 15 #Python
Django中ORM表的创建和增删改查方法示例
Nov 15 #Python
You might like
实测在class的function中include的文件中非php的global全局环境
2013/07/15 PHP
jQuery html() in Firefox (uses .innerHTML) ignores DOM changes
2010/03/05 Javascript
js判断鼠标同时离开两个div的思路及代码
2013/05/31 Javascript
javascript中负数算术右移、逻辑右移的奥秘探索
2013/10/17 Javascript
轻量级网页遮罩层jQuery插件用法实例
2015/07/31 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
JQuery 传送中文乱码问题的简单解决办法
2016/05/24 Javascript
AngularJS基础 ng-paste 指令简单示例
2016/08/02 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
2016/08/11 Javascript
详解获取jq ul第一个li定位的四种解决方案
2016/11/23 Javascript
详解webpack介绍&安装&常用命令
2017/06/29 Javascript
iframe高度自适应及隐藏滚动条的实例详解
2017/09/29 Javascript
vue2.0 computed 计算list循环后累加值的实例
2018/03/07 Javascript
微信小程序实现红包功能(后端PHP实现逻辑)
2018/07/11 Javascript
JS开发自己的类库实例分析
2019/08/28 Javascript
Vue可自定义tab组件用法实例
2019/10/24 Javascript
浅谈小程序globalData的那些事儿
2019/11/01 Javascript
基于vue+echarts 数据可视化大屏展示的方法示例
2020/03/09 Javascript
python 测试实现方法
2008/12/24 Python
Python简单调用MySQL存储过程并获得返回值的方法
2015/07/20 Python
深入解读Python解析XML的几种方式
2016/02/16 Python
python使用正则表达式匹配字符串开头并打印示例
2017/01/11 Python
Python基于TCP实现会聊天的小机器人功能示例
2018/04/09 Python
详解opencv Python特征检测及K-最近邻匹配
2019/01/21 Python
20行python代码的入门级小游戏的详解
2019/05/05 Python
聊聊python里如何用Borg pattern实现的单例模式
2019/06/06 Python
如何通过Python3和ssl实现加密通信功能
2020/05/09 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
Selenium结合BeautifulSoup4编写简单的python爬虫
2020/11/06 Python
pandas针对excel处理的实现
2021/01/15 Python
CPB肌肤之钥美国官网:Clé de Peau Beauté
2017/09/05 全球购物
Fresh馥蕾诗英国官网:法国LVMH集团旗下高端天然护肤品牌
2018/11/01 全球购物
请解释流与文件有什么不同
2016/07/29 面试题
在校学生职业规划范文
2014/01/08 职场文书
九年级科学教学反思
2014/01/29 职场文书
中学后勤工作总结2015
2015/07/22 职场文书