使用 python asyncio.Semaphore 循环启动一堆协程的正确方法是什么?

问题描述 投票:0回答:1

我想创建一个函数,通过使用 asyncio Semaphore 类来启动一堆协程,并等待所有协程完成。处理完这堆协程后,我想设置一个超时,等待运行下一组。

我曾尝试使用两个 for 循环来实现此目的,但我不太确定这是解决此问题的最佳方法。这是代码:

async def start(self):
        sem = asyncio.Semaphore(10)
        latest_block_number = await self.w3.eth.block_number
        tasks = []
        for i in range(latest_block_number, latest_block_number-self.blocks_needed, -10):
            for j in range(i, i - 10, -1):
                task = asyncio.create_task(self.get_transactions_of_block(current_block_number=j, sem=sem))
                tasks.append(task)

            await asyncio.gather(*tasks)
            tasks.clear()
            await asyncio.sleep(60)

你能帮我说说你的想法吗?谢谢!

python asynchronous python-asyncio semaphore
1个回答
0
投票

您可以使用

asyncio.gather()
来完成此操作。这会将所有内容聚集在一起(或者用技术术语来说,允许您使用异步 I/O 同时运行多个协程函数)并确保它们运行。然后您可以调用同步睡眠。

此外,还有一个文档链接:https://docs.python.org/3/library/asyncio-task.html

这是我不久前测试的一些代码,但我添加了一个 for 循环,每个循环之间也等待 5 秒。

import asyncio
import time


def main():
    ''' main entry point for the program '''
    # create the event loop and add to the loop
    # or run directly.

    asyncio.run(main_async())
    return

async def main_async():
    ''' the main async function '''
    # await foo()
    # await bar()
    for i in range(3):
        await asyncio.gather(foo(), bar())
        print('wait a bit..')
        time.sleep(5)
    return

async def foo():
    print('before the sleep')
    await asyncio.sleep(2)
    # time.sleep(2)
    print('world')
    return

async def bar():
    print('hello')
    await asyncio.sleep(0)
    return



if __name__=='__main__':
    ''' This is executed when run from the command line '''
    main()

上面的过程返回这个:

hello
world
wait a bit..
before the sleep
hello
world
wait a bit..
before the sleep
hello
world
wait a bit..
© www.soinside.com 2019 - 2024. All rights reserved.