python 主程序如何获取线程的执行结果

python 高并发开发中, 有时候主程序需要获取线程的执行结果, 然后再继续做些处理, 下面介绍几种方法:

1 利用 ThreadPoolExecutor 任务提交后的返回值对象 Future

直接上例子:

from concurrent.futures import ThreadPoolExecutor
import time

def task(n):
    time.sleep(n)  # 让任务暂停n秒, 模拟一个耗时的任务
    return n

executor = ThreadPoolExecutor(max_workers=1)  # 创建一个线程池,最大工作线程数为1
future = executor.submit(task, 2)  # 提交任务到线程池,参数是2, 返回一个 Future 对象

# 死循环, 监控future 的结果
while True:
    if future.done():  # 如果任务完成
        print("任务已完成")
        break
    elif future.running():  # 如果任务正在运行
        print("任务仍在运行")
    elif future.cancelled():  # 如果任务被取消
        print("任务已被取消")
    time.sleep(0.5)  # 每0.5秒检查一次任务状态

# 获取线程的执行结果
if future.done() and not future.cancelled():  # 如果任务完成且未被取消
    print("结果:", future.result())  # 打印任务结果

上述例子向ThreadPoolExecutor提交任务后, 拿到一个Future对象, 然后不停地检测 Future 对象的状态, 当状态是done的时候, 打印输出结果。

2 自定义Thread 利用 Future 对象

from concurrent.futures import Future
import threading
import time

def do_task(number, future):
    time.sleep(number)  # 根据输入的数字睡眠相应的秒数
    future.set_result(number ** 2 )  # 将该数字的平方设置为任务的结果

def do_task_async(number):
    future = Future()  # 创建一个 Future 对象
    t = threading.Thread(target=do_task, args=(number, future))  # 创建一个线程,目标函数是 do_task
    t.start()  # 启动线程
    return future  # 返回 Future 对象

future = do_task_async(5)  # 异步执行任务

# 死循环, 监控future 的结果
while True:
    if future.done():  # 如果任务完成
        print("任务已完成")
        break
    elif future.running():  # 如果任务正在运行
        print("任务仍在运行")
    elif future.cancelled():  # 如果任务被取消
        print("任务已被取消")
    else:
        print("任务仍在pending")  # 如果任务既没有完成,也没有在运行,也没有被取消,那么任务就是 pending 状态
    time.sleep(0.5)  # 每0.5秒检查一次任务状态

# 获取线程的执行结果
if future.done() and not future.cancelled():  # 如果任务完成且未被取消
    print("结果:", future.result())  # 打印任务结果

这个例子中我们自己定义的 Future对象从定义完成后, 一致是 pending 状态, 当被设置 set_result 后, 状态变为done. 这状态的变化和第一个例子是不一样的, ThreadPoolExecutor 提交任务后的future, 状态是running, 正常运行完成后才会变为 done.

实际上 也可以对 Future 设置回调函数, 设置当结束后, 执行某些操作, 感兴趣的可以查看如何设置回调函数: add_done_callback。

3 利用queue.Queue()

queue.Queue() 是 Python 标准库中 queue 模块的一个类,它提供了线程安全的队列实现。 queue.Queue() 创建一个先进先出(FIFO)的队列,可以在多个线程之间安全的共享和操作。它提供了一些主要的方法,包括:
put(item): 将一个元素添加到队列的末尾。
get(): 从队列的头部移除并返回一个元素。如果队列为空,这个方法会阻塞,直到有元素可用。
empty(): 如果队列为空,返回 True,否则返回 False。
full(): 如果队列已满,返回 True,否则返回 False。
qsize(): 返回队列中的元素数量。

直接看一个例子:

import threading
import queue
import time

def worker(num, output_queue):
    """线程工作函数。它会根据输入的数字睡眠相应的秒数,然后将该数字的平方放入输出队列。"""
    print('Worker:', num)  
    time.sleep(num)  # 模拟耗时任务
    output_queue.put(num ** 2)  # 将该数字的平方放入输出队列

# 创建一个队列来保存结果
q = queue.Queue()

# 创建一个列表来保存工作线程
threads = []

# 创建并启动工作线程
for i in range(5):
    t = threading.Thread(target=worker, args=(i, q))  # 创建一个工作线程
    threads.append(t)  # 将工作线程添加到列表中
    t.start()  # 启动工作线程

# 等待所有工作线程完成
for t in threads:
    t.join()

# 从队列中获取并打印结果
while not q.empty():
    print(q.get())  # 打印结果

print("all done")  # 表示所有工作线程已完成

例子中先定义可一个queue.Queue(), 然后作为参数传递到每一个线程中, 线程中的结果存储到queue中, 待线程结束后, 从q中获取线程的结果。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值