Python concurrent.futures 使用带回调的子进程
Python concurrent.futures using subprocess with a callback
我正在执行来自 Python 的 FORTRAN exe。 FORTRAN exe 需要很长时间才能完成;因此,我需要在 exe 完成时触发回调。该 exe 不会 return 返回 Python,但在回调函数中我将使用 Python 来解析来自 FORTRAN 的输出文本文件。
为此,我使用了 concurrent.futures
和 add_done_callback()
,并且有效。但是 Web 服务的这一部分,我需要有 Python 方法,在执行 FORTRAN exe 后调用 subprocess.call() / Popen()
到 return。然后当 FORTRAN 完成时调用回调函数。
def fortran_callback(run_type, jid):
return "Fortran finished executing"
def fortran_execute():
from concurrent.futures import ThreadPoolExecutor as Pool
args = "fortran.exe arg1 arg2"
pool = Pool(max_workers=1)
future = pool.submit(subprocess.call, args, shell=1)
future.add_done_callback(fortran_callback(run_type, jid))
pool.shutdown(wait=False)
return "Fortran executed"
fortran_execute() 在提交表单时调用,我想 return "Fortran executed" 无需等待 FORTRAN 完成。
目前 Python 方法 returns 无需等待 FORTRAN 完成,但它也会在 returns 时触发回调。 FORTRAN 进程继续 运行,当它最终完成时,它会尝试调用回调函数并抛出异常,因为 future
不再存在 TypeError: 'NoneType' object is not callable
.
使用 subprocess
启动 exe,具有函数 return,然后仅在 exe 执行完成时才调用回调方法,我在这里缺少什么?
好的,现在我知道你想要什么,你的问题是什么了。
def fortran_callback(future):
print(future.run_type, future.jid)
return "Fortran finished executing"
def fortran_execute():
from concurrent.futures import ProcessPoolExecutor as Pool
args = "sleep 2; echo complete"
pool = Pool(max_workers=1)
future = pool.submit(subprocess.call, args, shell=1)
future.run_type = "run_type"
future.jid = "jid"
future.add_done_callback(fortran_callback)
print("Fortran executed")
if __name__ == '__main__':
import subprocess
fortran_execute()
运行 上面的代码给出了输出:
$ python3 test.py
Fortran executed
complete
run_type jid
- 使用 ThreadPool 没问题,但如果
fortran_callback
计算量大 ,则 ProcessPool 更好
- 回调只有一个参数,就是future对象,所以你需要做的就是通过
future
的属性传递参数。
我正在执行来自 Python 的 FORTRAN exe。 FORTRAN exe 需要很长时间才能完成;因此,我需要在 exe 完成时触发回调。该 exe 不会 return 返回 Python,但在回调函数中我将使用 Python 来解析来自 FORTRAN 的输出文本文件。
为此,我使用了 concurrent.futures
和 add_done_callback()
,并且有效。但是 Web 服务的这一部分,我需要有 Python 方法,在执行 FORTRAN exe 后调用 subprocess.call() / Popen()
到 return。然后当 FORTRAN 完成时调用回调函数。
def fortran_callback(run_type, jid):
return "Fortran finished executing"
def fortran_execute():
from concurrent.futures import ThreadPoolExecutor as Pool
args = "fortran.exe arg1 arg2"
pool = Pool(max_workers=1)
future = pool.submit(subprocess.call, args, shell=1)
future.add_done_callback(fortran_callback(run_type, jid))
pool.shutdown(wait=False)
return "Fortran executed"
fortran_execute() 在提交表单时调用,我想 return "Fortran executed" 无需等待 FORTRAN 完成。
目前 Python 方法 returns 无需等待 FORTRAN 完成,但它也会在 returns 时触发回调。 FORTRAN 进程继续 运行,当它最终完成时,它会尝试调用回调函数并抛出异常,因为 future
不再存在 TypeError: 'NoneType' object is not callable
.
使用 subprocess
启动 exe,具有函数 return,然后仅在 exe 执行完成时才调用回调方法,我在这里缺少什么?
好的,现在我知道你想要什么,你的问题是什么了。
def fortran_callback(future):
print(future.run_type, future.jid)
return "Fortran finished executing"
def fortran_execute():
from concurrent.futures import ProcessPoolExecutor as Pool
args = "sleep 2; echo complete"
pool = Pool(max_workers=1)
future = pool.submit(subprocess.call, args, shell=1)
future.run_type = "run_type"
future.jid = "jid"
future.add_done_callback(fortran_callback)
print("Fortran executed")
if __name__ == '__main__':
import subprocess
fortran_execute()
运行 上面的代码给出了输出:
$ python3 test.py
Fortran executed
complete
run_type jid
- 使用 ThreadPool 没问题,但如果
fortran_callback
计算量大 ,则 ProcessPool 更好
- 回调只有一个参数,就是future对象,所以你需要做的就是通过
future
的属性传递参数。