300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > python多线程处理数据并获得子线程返回值

python多线程处理数据并获得子线程返回值

时间:2021-10-21 21:54:01

相关推荐

python多线程处理数据并获得子线程返回值

python多线程处理数据并获得子线程返回值

前言python3中的多线程用方法包装函数用类包装函数获取子线程返回值从类中返回值其他方法

前言

python中采用多线程方式处理大数据量的数据是比较常见和便捷的方法,而有时还想获取每个子线程运行得到的结果,因此将多线程处理和获取子线程返回值的方法做一总结。

python3中的多线程

两种方式:用方法包装函数、用类包装函数。

用方法包装函数

_thread.start_new_thread (func, args[, kwargs])

其中,func是线程函数,args是传递给线程函数的参数且类型必须是tuple,kwargs是可选参数。

注意:

在python2中,多线程函数模块为thread,但是在python3中该模块已被_thread继承,并重新定义了新的多线程模块threading_thread模块提供了低级别的、原始的线程以及一个简单的锁,它相比于threading模块的功能比较有限。

以下是一个通过_thread模块实现多线程的简单示例:

import _threadimport timedef print_time(thread_name, delay):c = 0while c < 5:time.sleep(delay)c += 1res = "%s: %s" % (thread_name, time.ctime(time.time()))print(res)# return res # 作为线程运行时函数中的return是无意义的if __name__ == "__main__":# 用方法包装线程try:try:_thread.start_new_thread(print_time, ("Thread-1", 1, ))_thread.start_new_thread(print_time, ("Thread-2", 2, ))except:pass# 谨慎使用此操作:极其耗费cpuwhile 1:time.sleep(0.1)except KeyboardInterrupt:print("You stop the threading.")

注意:

该方法因为需要while 1循环运行才能跑完多个线程,且无法自动退出,只能手动退出;由于while 1操作极耗内存,因此需加入sleep机制缓解此情况;考虑到threading模块构建类进行多线程操作更友好,因此实际应用中不采用此方法。

用类包装函数

首先通过threading模块构建多线程类MyThread.py

import threadingimport time# MyThread.py线程类class MyThread(threading.Thread):def __init__(self, func, args=()):super(MyThread, self).__init__()self.func = funcself.args = argsdef run(self):time.sleep(1)self.func(*self.args)

其中,func是线程函数,arg是传递给线程函数的参数且类型是tuple。

获取子线程返回值

获取子线程结果的方法不少,包括:

从类中返回值;设置全局队列写入返回值;通过multiprocessing.pool.ThreadPool获取返回值;通过concurrent.futures,结合set_result和result方法获取返回值等。

从类中返回值

从类中返回值是非常常见简便的方法,该方法的多线程类可以将上文中的MyThread.py文件稍作修改:

import threadingimport time# MyThread.py线程类class MyThread(threading.Thread):def __init__(self, func, args=()):super(MyThread, self).__init__()self.func = funcself.args = argsself.result = []def run(self):time.sleep(1)self.result = self.func(*self.args)def get_result(self):try:return self.resultexcept Exception:return None

在该方法的基础上,就可以实现返回子线程结果的功能了。

以下通过一个简单示例来说明:

from MyThread import MyThreaddef add(a, b):c = a + breturn cif __name__ == "__main__":# 用类包装线程ls = [23, 89]thr = []# 创建4个线程for i in range(4):task = MyThread(add, (ls[0], ls[1]))task.start()task.join()thr.append(task.get_result())print(thr)

这里写了一个简单的加法函数add,通过调用多线程类MyThread来实现获取子线程结果的功能。

这里需要注意两点:

一定要join子线程再get_result获取子线程结果,否则只会返回最后一个运行的子线程的结果。这是因为加入join阻塞后主线程必须等待所有子线程执行结束才会结束,那么每个子线程的结果都会通过task.get_result()获得。一定不能join加入MyThreadget_result中,这样虽然同样会获取子线程结果,但是多线程执行会失效。这一操作实质上是将多个线程顺序执行,因为在子线程中加入join阻塞后必须等待此子线程执行完才会执行下一个子线程,因此这一操作相当于将程序又变成单线程执行。

其他方法

其他方法暂时还没有研究和实操,等之后试过再写吧。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。