繁体   English   中英

在 python 中同时运行两个函数

[英]Run two functions concurrently in python

我有以下两个函数,我希望它们并行运行,就像我们在 Go 中使用 go 例程一样。 目前这些不并行运行。

请注意,每个函数中都没有异步代码,我需要使用两个函数返回的数据以备后用。

代码:

import asyncio

async def func1(i: int) -> int:
    print("Initiated func1")
    while i <= 100000000:
        i += 1
    print("Finished func1")
    return 100

async def func2() -> (str, int):
    print("Initiated func2")
    return "hello world", 200

async def main():
    res = await asyncio.gather(*(func1(10), func2()))
    return res

if __name__ == "__main__":
    data1, data2 = asyncio.run(main())
    print(f"func1: {data1}, func2: {data2}")

实际 output:

Initiated func1
Finished func1
Initiated func2
func1: 100, func2: ('hello world', 200)

预期 output:

Initiated func1
Initiated func2
Finished func1
func1: 100, func2: ('hello world', 200)

因为,您声明了不可等待的 func 。

# sync code block in func1: not awaitable
while i <= 100000000:
    i += 1

在 func 中添加asyncio.sleep(1)或使用concurrent.futures.ProcessPoolExecuto

In [1]: import asyncio
   ...:
   ...: async def func1(i: int) -> int:
   ...:     print("Initiated func1")
   ...:     await asyncio.sleep(1)
   ...:     print("Finished func1")
   ...:     return 100
   ...:
   ...: async def func2() -> (str, int):
   ...:     print("Initiated func2")
   ...:     await asyncio.sleep(1)
   ...:     return "hello world", 200
   ...:
   ...: async def main():
   ...:     res = await asyncio.gather(*(func1(10), func2()))
   ...:     return res
   ...:
   ...:

In [2]: await main()
Initiated func1
Initiated func2
Finished func1
Out[2]: [100, ('hello world', 200)]

In [3]: from concurrent.futures import ProcessPoolExecutor

In [4]: def func1(i: int) -> int:
   ...:     print("Initiated func1")
   ...:     while i <= 100000000:
   ...:         i += 1
   ...:     print("Finished func1")
   ...:     return 100
   ...:
   ...: def func2() -> (str, int):
   ...:     print("Initiated func2")
   ...:     return "hello world", 200
   ...:

In [5]: def main():
   ...:     with ProcessPoolExecutor(2) as pool:
   ...:         res = [pool.submit(func1, 10), pool.submit(func2)]
   ...:         return [res[0].result(), res[1].result()]
   ...:

In [6]: main()
Initiated func1
Initiated func2
Finished func1
Out[6]: [100, ('hello world', 200)]

您误解了async -functions 的并发性是如何工作的。 这与 go-routines 完全不同。 异步执行仍然发生在一个线程中。 事件循环只要遇到await可以切换执行。 这意味着,如果您不在async函数中执行 I/O 绑定任务,则根本不会有并发。

在 Python 中,即使线程也无济于事,但这已在此平台上进行了广泛讨论(搜索“GIL”)。 您只能通过 Python 使用多处理实现特定任务的有意义的并发。

如果我理解正确,您根本不需要处理async函数。 您可以为此使用multiprocessing模块。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM