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 相关文章推荐
在Django中限制已登录用户的访问的方法
Jul 23 Python
CentOS下使用yum安装python-pip失败的完美解决方法
Aug 16 Python
Python 反转字符串(reverse)的方法小结
Feb 20 Python
python实现requests发送/上传多个文件的示例
Jun 04 Python
利用python对Excel中的特定数据提取并写入新表的方法
Jun 14 Python
解决python中使用PYQT时中文乱码问题
Jun 17 Python
Python Numpy计算各类距离的方法
Jul 05 Python
python获取点击的坐标画图形的方法
Jul 09 Python
如何使用python传入不确定个数参数
Feb 18 Python
python tkinter 设置窗口大小不可缩放实例
Mar 04 Python
django-xadmin根据当前登录用户动态设置表单字段默认值方式
Mar 13 Python
13个Pandas实用技巧,助你提高开发效率
Aug 19 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
关于Intype一些小问题的解决办法
2008/03/28 PHP
jquery 简短几句代码实现给元素动态添加及获取提示信息
2011/09/01 Javascript
javascript实现淘宝幻灯片广告展示效果
2015/04/27 Javascript
jQuery结合CSS制作漂亮的select下拉菜单
2015/05/03 Javascript
JS模式之简单的订阅者和发布者模式完整实例
2015/06/30 Javascript
js淡入淡出的图片轮播效果代码分享
2015/08/24 Javascript
JS响应鼠标点击实现两个滑块区间拖动效果
2015/10/26 Javascript
jquery 将当前时间转换成yyyymmdd格式的实现方法
2016/06/01 Javascript
jquery点击展示与隐藏更多内容
2016/12/03 Javascript
bootstrap输入框组件使用方法详解
2017/01/19 Javascript
PHP实现本地图片上传和验证功能
2017/02/27 Javascript
原生JS+CSS实现炫酷重力模拟弹跳系统的登录页面
2017/11/01 Javascript
javascript、php关键字搜索函数的使用方法
2018/05/29 Javascript
详解原生JS动态添加和删除类
2019/03/26 Javascript
微信小程序上线发布流程图文详解
2019/05/06 Javascript
vue与django集成打包的实现方法
2019/11/11 Javascript
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
python搭建简易服务器分析与实现
2012/12/15 Python
Python random模块(获取随机数)常用方法和使用例子
2014/05/13 Python
Python构造函数及解构函数介绍
2015/02/26 Python
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
Python黑魔法Descriptor描述符的实例解析
2016/06/02 Python
在django中使用自定义标签实现分页功能
2017/07/04 Python
django+mysql的使用示例
2018/11/23 Python
python构建基础的爬虫教学
2018/12/23 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
2020/05/25 Python
python3让print输出不换行的方法
2020/08/24 Python
既然说Ruby中一切都是对象,那么Ruby中类也是对象吗
2013/01/26 面试题
制作部班长职位说明书
2014/02/26 职场文书
图书借阅制度范本
2015/08/06 职场文书
2016感恩母亲节校园广播稿
2015/12/17 职场文书
如何使JavaScript休眠或等待
2021/04/27 Javascript
Java基于Dijkstra算法实现校园导游程序
2022/03/17 Java/Android
JavaScript架构搭建前端监控如何采集异常数据
2022/06/25 Javascript
Java 中的 Lambda List 转 Map 的多种方法详解
2022/07/07 Java/Android