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中使用模块的教程
Apr 27 Python
python在指定目录下查找gif文件的方法
May 04 Python
使用python和pygame绘制繁花曲线的方法
Feb 24 Python
python批量替换多文件字符串问题详解
Apr 22 Python
Python3.6简单的操作Mysql数据库的三个实例
Oct 17 Python
解决python 自动安装缺少模块的问题
Oct 22 Python
新版Pycharm中Matplotlib不会弹出独立的显示窗口的问题
Jun 02 Python
OpenCV 之按位运算举例解析
Jun 19 Python
python实现学生成绩测评系统
Jun 22 Python
Python 如何反方向迭代一个序列
Jul 28 Python
python pygame 愤怒的小鸟游戏示例代码
Feb 25 Python
Python中else的三种使用场景
Jun 16 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
php Mysql日期和时间函数集合
2007/11/16 PHP
php表单转换textarea换行符的方法
2010/09/10 PHP
PHP中空字符串介绍0、null、empty和false之间的关系
2012/09/25 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
JavaScript 继承详解 第一篇
2009/08/30 Javascript
js 省地市级联选择
2010/02/07 Javascript
关于flash遮盖div浮动层的解决方法
2010/07/17 Javascript
jQuery 淡出一个图像到另一个图像的实现代码
2013/06/12 Javascript
Javascript学习笔记之函数篇(五) : 构造函数
2014/11/23 Javascript
JQuery中的事件及动画用法实例
2015/01/26 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
莱鸟介绍javascript onclick事件
2016/01/06 Javascript
AngularJS入门教程中SQL实例详解
2016/07/27 Javascript
Vue2实现组件props双向绑定
2016/12/02 Javascript
Vue 单文件中的数据传递示例
2017/03/21 Javascript
vue项目引入Iconfont图标库的教程图解
2018/10/24 Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
2019/08/16 Javascript
基于p5.js 2D图像接口的扩展(交互实现)
2020/11/30 Javascript
跟老齐学Python之编写类之一创建实例
2014/10/11 Python
Python函数式编程指南(二):从函数开始
2015/06/24 Python
使用Python生成随机密码的示例分享
2016/02/18 Python
python生成lmdb格式的文件实例
2018/11/08 Python
Python hashlib模块实例使用详解
2019/12/24 Python
Python实现敏感词过滤的4种方法
2020/09/12 Python
使用Python解析Chrome浏览器书签的示例
2020/11/13 Python
纯CSS3实现8组超炫酷鼠标滑过图片动画
2016/03/16 HTML / CSS
利用HTML5的新特点实现图片文件异步上传
2014/05/29 HTML / CSS
安德玛比利时官网:Under Armour比利时
2019/08/28 全球购物
乌克兰第一的珠宝网上商店:Gold.ua
2019/11/29 全球购物
生物医学工程专业学生求职信范文分享
2013/12/14 职场文书
学术诚信承诺书
2014/05/26 职场文书
2014年社区计生工作总结
2014/11/18 职场文书
八年级数学教学反思
2016/02/17 职场文书
Python中with上下文管理协议的作用及用法
2022/03/18 Python
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
2022/04/30 Vue.js