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 18 Python
Python使用arrow库优雅地处理时间数据详解
Oct 10 Python
Python键盘输入转换为列表的实例
Jun 23 Python
Django实现一对多表模型的跨表查询方法
Dec 18 Python
python爬取cnvd漏洞库信息的实例
Feb 14 Python
python初学者,用python实现基本的学生管理系统(python3)代码实例
Apr 10 Python
python画图常规设置方式
Mar 05 Python
关于Python turtle库使用时坐标的确定方法
Mar 19 Python
使用keras实现BiLSTM+CNN+CRF文字标记NER
Jun 29 Python
Python实现京东抢秒杀功能
Jan 25 Python
Django中如何用xlwt生成表格的方法步骤
Jan 31 Python
python实战之一步一步教你绘制小猪佩奇
Apr 22 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用户指南-cookies部分
2006/10/09 PHP
两级联动select刷新后其值保持不变的实现方法
2014/01/27 PHP
PHP实现的注册,登录及查询用户资料功能API接口示例
2017/06/06 PHP
PHP实现基于回溯法求解迷宫问题的方法详解
2017/08/17 PHP
use jscript List Installed Software
2007/06/11 Javascript
Jquery中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
2011/10/12 Javascript
jQuery中remove()方法用法实例
2014/12/25 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
2015/04/03 Javascript
基于JS实现数字+字母+中文的混合排序方法
2016/06/06 Javascript
快速解决js开发下拉框中blur与click冲突
2016/10/10 Javascript
Linux使用Node.js建立访问静态网页的服务实例详解
2017/03/21 Javascript
React-Native中禁用Navigator手势返回的示例代码
2017/09/09 Javascript
node.js中http模块和url模块的简单介绍
2017/10/06 Javascript
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
[00:55]深扒TI7聊天轮盘语音出处3
2017/05/11 DOTA
python根据出生日期获得年龄的方法
2015/03/31 Python
Django中的forms组件实例详解
2018/11/08 Python
python的concat等多种用法详解
2018/11/28 Python
Python API 自动化实战详解(纯代码)
2019/06/11 Python
Django框架 Pagination分页实现代码实例
2019/09/04 Python
Python爬虫爬取博客实现可视化过程解析
2020/06/29 Python
python3.7添加dlib模块的方法
2020/07/01 Python
基于opencv实现简单画板功能
2020/08/02 Python
美国专营婴幼儿用品的购物网站:buybuy BABY
2017/01/01 全球购物
Linux如何命名文件--使用文件名时应注意
2012/01/22 面试题
电大自我鉴定
2013/10/27 职场文书
村优秀党员事迹材料
2014/01/15 职场文书
优秀经理事迹材料
2014/02/01 职场文书
美容院营销方案
2014/03/05 职场文书
医院深入开展党的群众路线教育实践活动实施方案
2014/08/27 职场文书
开平碉楼导游词
2015/02/06 职场文书
面试通知短信
2015/04/20 职场文书
2015年保洁工作总结范文
2015/04/28 职场文书
婚礼必备主持词范本!
2019/07/23 职场文书
CSS3实现的侧滑菜单
2021/04/27 HTML / CSS