Упорядоченное выполнение для Python asyncio.Semaphore - PullRequest
0 голосов
/ 25 марта 2020

Я запускаю несколько параллельных выполнений с asyncio.Semaphore над заказанным List.

    async def send_cus(cus_id):
        async with ClientSession(connector=TCPConnector(limit=0)) as session:
            num_parallel = asyncio.Semaphore(20)

            async def send_cust_2(cust_id):
                async with num_parallel:
                    # do something ...

            tasks = list(
                send_cust_2(cust_id)
                for cus_id in my_ordered_lst
            )
            await asyncio.gather(*tasks)

Дело в том, что он выполняется неупорядоченным образом, независимо от порядка my_ordered_lst , Я понимаю, что это потому, что мы не можем гарантировать гарантированный порядок выполнения для потоков или разветвлений процессов без синхронизации элементов.

Есть ли способ получить упорядоченное выполнение в течение List, при этом все еще имея параллельное выполнение? Как сначала отправить 1-й. получить блокировку, отправить, затем отправить, получить блокировку и т. д.

1 Ответ

3 голосов
/ 25 марта 2020

До Python 3.7 asyncio.gather() запускал задачи в произвольном порядке. Для 3.7 он был переписан для эффективности с побочным эффектом, что теперь он создает задачи в указанном порядке.

В Python 3.6 и ранее вы можете обойти проблему, порождая Задачи вручную в нужном порядке, а затем вызывая gather, чтобы дождаться их окончания sh:

tasks = [asyncio.create_task(send_cust_2(cust_id))
         for cust_id in my_ordered_lst]
await asyncio.gather(*tasks)

Обратите внимание, что это просто запуск задач в указанном порядке , То, как они продолжат выполнение после первого await, будет зависеть от того, что делают отдельные задачи, и от времени их соответствующих операций.

...