• python使用threading获取线程函数返回值的实现方法


    python使用threading获取线程函数返回值的实现方法

    这篇文章主要介绍了python使用threading获取线程函数返回值的实现方法,需要的朋友可以参考下

    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 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

      CDA大数据分析圈是国内第一个汇聚大数据全面资源、数据人必备的APP。CDA整合了近千个大数据相关专业网站及媒体来源,汇聚了数百场国内大数据活动与会议,数千名名技术大牛、行业领袖,以及总结了最系统的优质学习课程资源。在这里,你可每天接触到最新行业资讯、前沿技术干货等信息;你可参与CDA俱乐部活动、各类大型会议,亲身与大牛接触,获得实务经验。你也可在专业课堂上与国内顶尖讲师进行交流切磋,最有效规划自身大数据职业发展。
      CDA大数据分析圈是数据人的家园,圈子里,资源流通,共享智慧,合作发展。CDA以“创新、开放、分享”的理念,期待你的加入!

  • 相关阅读:
    素数个数(素数➕dfs)
    最小正子段和
    set<int> 的用法
    C
    map的用法
    B
    威佐夫博弈
    Stars(树状数组)
    upper_bound和lower_bound的用法
    超级大水题(还是自己过不了的水题)
  • 原文地址:https://www.cnblogs.com/amengduo/p/9586704.html
Copyright © 2020-2023  润新知