Получение блокировки непосредственно перед запуском asyn c метода - PullRequest
0 голосов
/ 15 апреля 2020

Допустим, у меня есть экземпляр multiprocessing.Lock (lock ниже), который я хочу приобрести непосредственно перед тем, как на самом деле начнет работать сопрограмма foo (скажем, она будет вызвана некоторым будущим вводом / выводом или сигналом, и поэтому я не хочу удерживать блокировку на весь период, когда она заблокирована, а только на время ее работы.) Есть ли способ сделать это без изменения самого тела foo? Для иллюстрации:

Без блокировки:

await foo()

С блокировкой:

lock.acquire()
await foo()
lock.release()

Насколько я могу судить, это не помогает обернуть foo внутри другая async функция, потому что она все еще должна быть await отредактированной таким же образом. Это также не помогает иметь дело с asyncio.Future напрямую, потому что все, что я могу сделать, это add_done_callback. Или любая другая концепция «цепочки» обратных вызовов - это то же самое, что обернуть ее в функцию async - если я поставлю будущее получения блокировки перед будущим foo, оно будет эффективно работать сразу же, и блокировка будет удерживается в течение всей продолжительности до тех пор, пока foo фактически не начнется.

Меняет ли тело foo единственный путь или есть обходной путь, которого я не вижу?


К Будьте немного более конкретны c в случае, если это проливает свет, моя ситуация на самом деле такова, что foo - это get метод экземпляра asyncio.Queue. Поэтому может быть достаточно подкласса и переопределения этого однострочного метода с помощью двухстрочного, который сначала выполняет желаемое получение блокировки. Или monkeypatch метод в экземпляре. Но это похоже на уродливую территорию.

https://github.com/python/cpython/blob/1e1dbdf23f7a18f53a3257badc3541973831f2c4/Lib/asyncio/queues.py#L57 -L58

1 Ответ

0 голосов
/ 15 апреля 2020

Обновлено после комментария.

Как правило, при использовании замков их следует удерживать в течение наименьшую возможную продолжительность .

Написание подкласса - это, вероятно, путь к go, если вам нужно использовать блокировки.

В вашем вопросе недостаточно подробностей, чтобы дать другие разумные рекомендации.

...