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栈类实例分析
Jun 15 Python
Python和JavaScript间代码转换的4个工具
Feb 22 Python
利用Python实现命令行版的火车票查看器
Aug 05 Python
python的dataframe转换为多维矩阵的方法
Apr 11 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
Jun 19 Python
解决Django中多条件查询的问题
Jul 18 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
Jan 23 Python
Tensorflow中的dropout的使用方法
Mar 13 Python
使用Python防止SQL注入攻击的实现示例
May 21 Python
详解tensorflow2.x版本无法调用gpu的一种解决方法
May 25 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
Jan 06 Python
如何理解python接口自动化之logging日志模块
Jun 15 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
SONY ICF-SW7600的电路分析
2021/03/02 无线电
建立文件交换功能的脚本(二)
2006/10/09 PHP
深入理解PHP中的global
2014/08/19 PHP
Yii2 RESTful中api的使用及开发实例详解
2016/07/06 PHP
CI框架AR数据库操作常用函数总结
2016/11/21 PHP
PHP接口继承及接口多继承原理与实现方法详解
2017/10/18 PHP
JQuery 实现的页面滚动时浮动窗口控件
2009/07/10 Javascript
javascript 获取元素位置的快速方法 getBoundingClientRect()
2009/11/26 Javascript
JQuery中操作Css样式的方法
2014/02/12 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
jQuery实现非常实用漂亮的select下拉菜单选择效果
2015/11/06 Javascript
js弹出对话框方式小结
2015/11/17 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
2016/01/15 Javascript
jQuery on()绑定动态元素出现的问题小结
2016/02/19 Javascript
深入浅析Vue中的Prop
2018/06/10 Javascript
React优化子组件render的使用
2019/05/12 Javascript
JS数组扁平化(flat)方法总结详解
2019/06/24 Javascript
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
2020/12/02 Vue.js
[03:05]DOTA2英雄基础教程 嗜血狂魔
2013/12/10 DOTA
[48:54]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第二场 6.3
2018/06/04 DOTA
初学Python函数的笔记整理
2015/04/07 Python
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
Python实现的矩阵类实例
2017/08/22 Python
python实现秒杀商品的微信自动提醒功能(代码详解)
2020/04/27 Python
纯CSS3+DIV实现小三角形边框效果的示例代码
2020/08/03 HTML / CSS
html5实现完美兼容各大浏览器的播放器
2014/12/26 HTML / CSS
伦敦平价潮流珠宝首饰品牌:Astrid & Miyu
2016/10/10 全球购物
家得宝官网:The Home Depot(全球最大的家居装饰专业零售商)
2018/12/17 全球购物
美国糖果店:Sugarfina
2019/02/21 全球购物
西班牙品牌鞋子、服装和配饰在线商店:Esdemarca
2021/02/17 全球购物
linux比较文件内容的命令是什么
2013/03/04 面试题
留学自荐信写作方法
2014/01/27 职场文书
电力培训心得体会
2014/09/02 职场文书
2014年采购员工作总结
2014/11/18 职场文书
高三毕业感言
2015/07/30 职场文书
《分数乘法》教学反思
2016/02/24 职场文书