Python3 多线程并发处理的返回值收集

库函数

threading

背景

去查询python3多线程,可以找到一大堆关于threading库的博客教程,但是多数是几个线程执行同一个函数(他们博客里各个线程传入的函数参数不同),且没有考虑获取函数的返回值.
我基于现有资料,对threading的应用又进行了以下扩展:

  • 面向对象的继承封装
  • 包含多个线程
  • 包含返回值
  • 包含多个函数
  • 代码结构极其简单

代码1

import threading
import time
from math import sqrt

class Demo(threading.Thread):       # 注意继承关系
    def __init__(self, func, args=()): # 指定函数和参数
        super(Demo, self).__init__()   # 切记别忘了
        self.func = func
        self.args = args

    def run(self):
        self.result = self.func(*self.args)

    def get_result(self):  # 完全自定义一个返回函数, 设置返回值
        try:
            return self.result  # 如果子线程不使用join方法,此处可能会报没有self.result的错误
        except Exception:
            return None

def Add(num):
    time.sleep(1)
    return num+100

def Sub(num):
    time.sleep(1)
    return num-100

def Mul(num):
    time.sleep(1)
    return num*100

def Sqrt(num):
    time.sleep(1)
    return sqrt(abs(num)+1)

def task_run():
    try:

        FuncL = (Add,Sub,Mul,Sqrt)
        ThreadL = []      # 存储各个线程
        ResL = []   # 存储各个线程的返回值
        for i in range(4):
            ThreadL.append(Demo(func=FuncL[i], args=(i,)))
        for _t in ThreadL:
            _t.start()
        for _t in ThreadL:
            _t.join()
            ResL.append(_t.get_result())
        return ResL
    
    except Exception as err:
        print(str(err))
    
if __name__ == '__main__':
    x = task_run()
    print("--------")
    print(x)

执行效果


这里列表的输出有1s的停顿.

原理

背后的原理是在Demo类对象里面完全自定义一个返回函数get_result(), 函数体内设置返回值. task_run()函数的内容可以完全写在main()函数里,效果一样;现在这样写是为了简化main函数逻辑.

可以继续魔改Demo类的内容,修改原来的join()函数,新增一句输出内容.并利用了threading.Thread()自带的name参数.请看如下代码:

代码2

import threading
import time
from math import sqrt

class Demo(threading.Thread):       # 注意继承关系
    def __init__(self, func, name, args=()): # 指定函数和参数
        super(Demo, self).__init__()   # 切记别忘了
        self.func = func
        self.name = name
        self.args = args

    def run(self):
        self.result = self.func(*self.args)

    def get_result(self):
        try:
            return self.result  # 如果子线程不使用join方法,此处可能会报没有self.result的错误
        except Exception:
            return None
    
    def join(self):
        super(Demo, self).join()
        print(f" Thread #{self.name} End! ")

def Add(num):
    time.sleep(1)
    return num+100

def Sub(num):
    time.sleep(1)
    return num-100

def Mul(num):
    time.sleep(1)
    return num*100

def Sqrt(num):
    time.sleep(1)
    return sqrt(abs(num)+1)

def task_run():
    try:

        FuncL = (Add,Sub,Mul,Sqrt)
        ThreadL = []      # 存储各个线程
        ResL = []   # 存储各个线程的返回值
        for i in range(4):
            ThreadL.append(Demo(func=FuncL[i], args=(i,), name=str(i)*5))
        for _t in ThreadL:
            _t.start()
        for _t in ThreadL:
            _t.join()
            ResL.append(_t.get_result())
        return ResL
    
    except Exception as err:
        print(str(err))
    
if __name__ == '__main__':
    x = task_run()
    print("--------")
    print(x)

执行效果

IP

111.231.64.195

posted @ 2022-12-08 09:59  爱吃砂糖橘的白龙  阅读(602)  评论(0编辑  收藏  举报