简体   繁体   English

在 python 中同时运行两个函数

[英]Run two functions concurrently in python

I have the two functions below and I want them to run in parallel just like we use go routines in Go.我有以下两个函数,我希望它们并行运行,就像我们在 Go 中使用 go 例程一样。 Currently these do not run in parallel.目前这些不并行运行。

Please note that there is no async code in each of the functions, and I need to use returned data from both functions for later use.请注意,每个函数中都没有异步代码,我需要使用两个函数返回的数据以备后用。

Code:代码:

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}")

Actual output:实际 output:

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

Expected output:预期 output:

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

because, you declare func that is not awaitable.因为,您声明了不可等待的 func 。

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

add asyncio.sleep(1) in func or use concurrent.futures.ProcessPoolExecuto在 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)]

You misunderstand how concurrency with async -functions works.您误解了async -functions 的并发性是如何工作的。 It's nothing like go-routines.这与 go-routines 完全不同。 The asynchronous execution still happens in one single thread .异步执行仍然发生在一个线程中。 The event loop just may switch execution whenever it encounters an await .事件循环只要遇到await可以切换执行。 This means, if you aren't doing I/O-bound tasks in your async functions, there will be no concurrency at all.这意味着,如果您不在async函数中执行 I/O 绑定任务,则根本不会有并发。

Even Threading will not help you in Python, but this has been discussed extensively on this platform (search for "GIL").在 Python 中,即使线程也无济于事,但这已在此平台上进行了广泛讨论(搜索“GIL”)。 You can only achieve meaningful concurrency with your particular task with Python using multiprocessing.您只能通过 Python 使用多处理实现特定任务的有意义的并发。

If I understand you correctly, you don't need to deal with async functions at all.如果我理解正确,您根本不需要处理async函数。 You can just use the multiprocessing module for this.您可以为此使用multiprocessing模块。

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

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