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基于回溯法子集树模板解决取物搭配问题实例
Sep 02 Python
Python设计模式之代理模式简单示例
Jan 09 Python
python3+PyQt5重新实现自定义数据拖放处理
Apr 19 Python
Python利用ORM控制MongoDB(MongoEngine)的步骤全纪录
Sep 13 Python
用python一行代码得到数组中某个元素的个数方法
Jan 28 Python
Python常用模块sys,os,time,random功能与用法实例分析
Jan 07 Python
pytorch的batch normalize使用详解
Jan 15 Python
Python3 获取文件属性的方式(时间、大小等)
Mar 12 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
Apr 23 Python
Python3与fastdfs分布式文件系统如何实现交互
Jun 23 Python
Python3中FuzzyWuzzy库实例用法
Nov 18 Python
PyTorch 中的傅里叶卷积实现示例
Dec 11 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
用Flash图形化数据(一)
2006/10/09 PHP
探讨Smarty中如何获取数组的长度以及smarty调用php函数的详解
2013/06/20 PHP
php导出中文内容excel文件类实例
2015/07/06 PHP
PhpStorm 2020.3:新增开箱即用的PHP 8属性(推荐)
2020/10/30 PHP
学习YUI.Ext 第六天--关于树TreePanel(Part 2异步获取节点)
2007/03/10 Javascript
javascript之bind使用介绍
2011/10/09 Javascript
深入浅析search 搜索框的写法
2016/08/02 Javascript
nodejs微信公众号支付开发
2016/09/19 NodeJs
微信小程序开发之animation循环动画实现的让云朵飘效果
2017/07/14 Javascript
微信小程序报错:this.setData is not a function的解决办法
2017/09/27 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
2018/07/03 Javascript
微信小程序url传参写变量的方法
2018/08/09 Javascript
Vue 莹石摄像头直播视频实例代码
2018/08/31 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
2019/01/08 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
2019/04/17 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
vue 单页应用和多页应用的优劣
2020/10/22 Javascript
基于javascript实现放大镜特效
2020/12/03 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
Python使用Mechanize模块编写爬虫的要点解析
2016/03/31 Python
Python部署web开发程序的几种方法
2017/05/05 Python
Python制作动态字符图的实例
2019/01/27 Python
详解Python对JSON中的特殊类型进行Encoder
2019/07/15 Python
浅析Python迭代器的高级用法
2020/07/16 Python
python脚本第一行如何写
2020/08/30 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
世界上最好的儿童品牌:AlexandAlexa
2018/01/27 全球购物
Android笔试题总结
2014/11/29 面试题
学生自我评价范文
2014/02/02 职场文书
结婚周年感言
2014/02/24 职场文书
超越自我演讲稿
2014/05/21 职场文书
党建工作整改措施
2014/10/28 职场文书
起诉状范本
2015/05/20 职场文书
横空出世观后感
2015/06/09 职场文书
用Python将GIF动图分解成多张静态图片
2021/06/11 Python