库函数
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)