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使用mailbox打印电子邮件的方法
Apr 30 Python
django 创建过滤器的实例详解
Aug 14 Python
Python使用回溯法子集树模板解决爬楼梯问题示例
Sep 08 Python
django+echart绘制曲线图的方法示例
Nov 26 Python
详解pandas安装若干异常及解决方案总结
Jan 10 Python
python中的RSA加密与解密实例解析
Nov 18 Python
Python爬虫库requests获取响应内容、响应状态码、响应头
Jan 25 Python
python+selenium+chromedriver实现爬虫示例代码
Apr 10 Python
Jupyter加载文件的实现方法
Apr 14 Python
基于Keras 循环训练模型跑数据时内存泄漏的解决方式
Jun 11 Python
python源文件的字符编码知识点详解
Mar 04 Python
Python中使用tkFileDialog实现文件选择、保存和路径选择
May 20 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实现俄罗斯乘法实例
2015/03/07 PHP
php实现的单一入口应用程序实例分析
2015/09/23 PHP
js 调整select 位置的函数
2008/02/21 Javascript
Javascript 中介者模式实例
2009/12/16 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
2013/01/23 Javascript
jQuery学习笔记之toArray()
2014/06/09 Javascript
用js判断是否为360浏览器的实现代码
2015/01/15 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
JS实现的文字与图片定时切换效果代码
2015/10/06 Javascript
AngularJs学习第八篇 过滤器filter创建
2016/06/08 Javascript
浅谈js基本数据类型和typeof
2016/08/09 Javascript
AngularJS定时器的使用与移除操作方法【interval与timeout】
2016/12/14 Javascript
总结几道关于Node.js的面试问题
2017/01/11 Javascript
从零开始学习Node.js系列教程四:多页面实现的数学运算示例
2017/04/13 Javascript
jQuery实现下拉菜单的实例代码
2017/06/19 jQuery
在vue中使用防抖和节流,防止重复点击或重复上拉加载实例
2019/11/13 Javascript
vue中v-for循环选中点击的元素并对该元素添加样式操作
2020/07/17 Javascript
解决echarts数据二次渲染不成功的问题
2020/07/20 Javascript
[01:15]PWL S2开团时刻第二期——他们杀 我就白给
2020/11/25 DOTA
python从入门到精通(DAY 3)
2015/12/20 Python
利用Python实现网络测试的脚本分享
2017/05/26 Python
Python工程师面试必备25条知识点
2018/01/17 Python
python 信息同时输出到控制台与文件的实例讲解
2018/05/11 Python
Pycharm如何打断点的方法步骤
2019/06/13 Python
pycharm new project变成灰色的解决方法
2019/06/27 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
Flask-SocketIO服务端安装及使用代码示例
2020/11/26 Python
纯CSS3实现的8种Loading动画效果
2014/07/05 HTML / CSS
自定义html标记替换html5新增元素
2008/10/17 HTML / CSS
Nike德国官网:Nike.com (DE)
2018/11/13 全球购物
极度干燥澳大利亚官方网站:Superdry澳大利亚
2019/03/28 全球购物
我的梦中国梦演讲稿
2014/04/23 职场文书
三好学生先进事迹材料
2014/08/28 职场文书
幼儿教师辞职信
2015/02/27 职场文书
安娜卡列尼娜观后感
2015/06/11 职场文书
JS实现页面炫酷的时钟特效示例
2022/08/14 Javascript