如何从另一个函数进行异步函数调用?

Posted

技术标签:

【中文标题】如何从另一个函数进行异步函数调用?【英文标题】:How do I make an asynchronous function call from another function? 【发布时间】:2020-04-02 07:01:08 【问题描述】:

目标是在执行程序其余部分的过程中并行创建一个 docx 文档。

“第一个”函数应该只调用将创建 docx 的异步“第二个”函数。 现在我使用模块 asyncio、multiprocessing、concurrent.futures,但没有创建 docx:

def first(self, event):
    pool = ThreadPoolExecutor(max_workers=multiprocessing.cpu_count())
    loop = asyncio.get_event_loop()
    loop.run_in_executor(pool, self.second)

async def second(self):
    document = Document()
    document.save('test.docx')

我确定问题出在“第一个”函数上,它调用“第二个”的方式,但有人对我说,这不是异步的错。在我找到最接近解决方案的方法之前,我一直面临这样一个问题,即只有在整个程序执行过程完成后才创建文档——这不是目标。

我正在处理一个没有时间修复的旧项目;里面的基本东西有很多错误,所以浏览器没有帮助 - 它需要针对具体情况的东西。即便如此,请告诉我如何解决这个问题。 谢谢。

【问题讨论】:

如果你只需要并行调用一个函数,你不应该使用asyncio。只需使用concurrent.futures @giacomo-alzetta,请告诉我如何在上面的代码示例中做到这一点? 【参考方案1】:

无需创建second async。我假设您可以将其更改为常规功能。

您可能只想在后台操作系统线程中开始创建文件:

def first():
    with ThreadPoolExecutor(max_workers=1) as executor:
        fut = executor.submit(second)  # start `second` in background

        # rest of the program

        fut.result()  # make sure `second` is finished


def second():
    document = Document()
    document.save('test.docx')

如果瓶颈是磁盘 I/O,这应该可以解决问题。如果瓶颈是 CPU,您应该考虑使用ProcessPoolExecutor 而不是ThreadPoolExecutor


这是可重现的代码:

import time
from concurrent.futures import ThreadPoolExecutor


def first():
    with ThreadPoolExecutor(max_workers=1) as executor:
        fut = executor.submit(second)  # start `second` in background

        print('Rest of the program started')
        time.sleep(2)  # rest of the program
        print('Rest of the program finished')

        fut.result()  # make sure `second` is finished


def second():
    time.sleep(1)  # create doc
    print('Doc created')


first()

【讨论】:

以上是关于如何从另一个函数进行异步函数调用?的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个成员函数调用成员函数指针?

如何在 Java 中从另一个构造函数调用一个构造函数?

如何从另一个构造函数调用 C++ 类构造函数 [重复]

如何从另一个类调用方法函数?

如何快速从另一个控制器调用函数

如何从另一个文件调用函数?