Невозможно использовать блокировку сбора в Python asyncioPython

Программы на Python
Ответить
Anonymous
 Невозможно использовать блокировку сбора в Python asyncio

Сообщение Anonymous »

По какой-то причине этот код не работает в Ubuntu 20, Python 3.8.10, если строка .gather не закомментирована.
Он работает в Ubuntu 24, Python 3.12.3 и Windows 11, Python 3.13.9.
Он не работает в Python 3.8/3.9 на той же машине с Ubuntu 24. Кажется, он работает начиная с Python 3.10, поэтому проблема, похоже, связана с версией Python.
Этот код представляет собой минимальный рабочий пример проблемы, с которой я столкнулся.
Предположим, что блокировки действительно необходимы.

Код: Выделить всё

import asyncio
import time

lock = asyncio.Lock()

async def action():
print("action")
return

async def task1():
while True:
print("1 waiting")
await lock.acquire()
print("1 running")
await asyncio.gather(*[action() for _ in range(1)])
lock.release()
print("1 unlocked")

print("A", time.time())
await asyncio.sleep(1)
print("B", time.time())

async def task2():
while True:
print("2 waiting")
await lock.acquire()
print("2 running")
lock.release()
print("2 unlocked")
await asyncio.sleep(1)

async def main():
task1_ = asyncio.create_task(task1())
task2_ = asyncio.create_task(task2())

while True: await asyncio.sleep(float('inf'))

if __name__ == "__main__":
asyncio.run(main())
Вывод в одной из работающих версий Python:

Код: Выделить всё

$ python3 test.py
1 waiting
1 running
2 waiting
action
1 unlocked
A 1763606395.8323498
2 running
2 unlocked
B 1763606396.843853
1 waiting
1 running
2 waiting
action
1 unlocked
A 1763606396.8451693
2 running
2 unlocked
B 1763606397.8484037
Обратите внимание, что задача 2 выполняется между A и B (пока задача 1 спит).
Вывод неработающих версий:

Код: Выделить всё

$ python3 test.py
1 waiting
1 running
2 waiting
action
1 unlocked
A 1763606434.4998655
B 1763606435.5010738
1 waiting
1 running
action
1 unlocked
A 1763606435.5020432
B 1763606436.5031264
1 waiting
1 running
action
1 unlocked
A 1763606436.5039277
B 1763606437.5050313
Как видите, задача 2 не выполняется между A и B.
Эта проблема возникает независимо от использования await lock.acquire() или async с lock:.
Если я закомментирую строку .gather, она будет работать во всех версиях.
Однако мне нужно запускать несколько задач одновременно, поэтому я не могу просто закомментировать это.
Я мне не удалось найти в документации ничего, что указывало бы на проблему со сбором или блокировками в старых версиях asyncio.
Так что же здесь происходит и как это исправить?

Подробнее здесь: https://stackoverflow.com/questions/798 ... on-asyncio
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»