从线程函数中获取值

Get value from threading function

我有两个函数想同时 运行 检查性能,现在我要 运行 一个接一个地 运行 并且需要相当长的时间。

我就是这样 运行宁

import pandas as pd
import threading
    
df = pd.read_csv('data/Detalhado_full.csv', sep=',', dtype={'maquina':str})

def gerar_graph_36():
    df_ordered = df.query(f'maquina=="3.6"')[['data', 'dia_semana', 'oee', 'ptg_ruins', 'prod_real_kg', 'prod_teorica_kg']].sort_values(by='data')
    oee = df_ordered['oee'].iloc[-1:].iloc[0]
    return oee

def gerar_graph_31():
    df_ordered = df.query(f'maquina=="3.1"')[['data', 'dia_semana', 'oee', 'ptg_ruins', 'prod_real_kg', 'prod_teorica_kg']].sort_values(by='data')
    oee = df_ordered['oee'].iloc[-1:].iloc[0]
    return oee

oee_36 = gerar_graph_36()
oee_31 = gerar_graph_31()

print(oee_36, oee_31)

我尝试使用此语句应用线程,但它不是 return 变量,而是打印 None

print(oee_31, oee_36) -> 预期:106.3 99.7 // 返回 None None

oee_31 = threading.Thread(target=gerar_graph_31, args=()).start()
oee_36 = threading.Thread(target=gerar_graph_36, args=()).start()
print(oee_31, oee_36)

为了检查目的,如果我使用下面的命令,returns 3 as expected

print(threading.active_count())

我需要函数的 return oee 值,例如 103.8。

提前致谢!!

通常创建一个新线程并启动它不像调用一个 returns 变量的函数:Thread.start() 调用只是“启动另一个线程的代码”,并且 returns 立即。

要在其他线程中收集结果,您必须使用某种数据结构将计算结果传送到主线程。一个普通的列表或字典就可以了,或者可以使用 queue.Queue.

如果你想要更像函数调用的东西并且不能修改 gerar_graph() 函数,你可以使用 concurrent.futures module 而不是线程:这是更高级别的代码将您的调用包装在“未来”对象中,您将能够检查每个未来何时完成并获取函数返回的值。

否则,只需要一个包含列表的 top-level 变量,等待您的线程完成 运行(当“目标”returns 调用函数时它们会停止),并收集结果:


import pandas as pd
import threading
    
df = pd.read_csv('data/Detalhado_full.csv', sep=',', dtype={'maquina':str})

results = []

def gerar_graph_36():
    df_ordered = df.query(f'maquina=="3.6"')[['data', 'dia_semana', 'oee', 'ptg_ruins', 'prod_real_kg', 'prod_teorica_kg']].sort_values(by='data')
    oee = df_ordered['oee'].iloc[-1:].iloc[0]
    results.append(oee)

def gerar_graph_31():
    df_ordered = df.query(f'maquina=="3.1"')[['data', 'dia_semana', 'oee', 'ptg_ruins', 'prod_real_kg', 'prod_teorica_kg']].sort_values(by='data')
    oee = df_ordered['oee'].iloc[-1:].iloc[0]
    results.append(oee)

# We need to keep a reference to the threads themselves
# so that we can call both ".start()" (which always returns None)
# and ".join()" on them.
oee_31 = threading.Thread(target=gerar_graph_31); oee_31.start()
oee_36 = threading.Thread(target=gerar_graph_36); oee_36.start()

oee_31.join() # will block and return only when the task is done, but oee_36 will be running concurrently
oee_36.join()
print(results)


如果您需要超过 2 个线程(比如全部 36 个...),我强烈建议使用 concurrent.futures:您可以将工作线程的数量限制为与您拥有的逻辑 CPU 相当的数量。而且,当然,在列表或字典中管理您的任务和调用,而不是为每个单独的变量名称。