Let's say I have a multiprocessing.Lock
instance ( lock
below) that I want to acquire just before a coroutine foo
actually begins to run (say it is triggered by some future I/O or signal and so I don't want to hold the lock for the entire period that it is blocked, but rather just while it runs.) Is there any way to do this without modifying the body of foo
itself? To illustrate:
Without lock:
await foo()
With lock:
lock.acquire()
await foo()
lock.release()
As far as I can tell it doesn't help to wrap foo
inside another async
function because it still needs to be await
ed in the same manner. It also doesn't help to deal with the asyncio.Future
directly, because all I can do is add_done_callback
. Or any other concept of "chaining" callbacks is the same as wrapping it in an async
function-- if I put the lock acquisition future before the foo
future, it will just run right away effectively, and the lock will be held for the whole duration until foo
actually begins.
Is changing the body of foo
the only way or is there a workaround I'm not seeing?
To be a little more specific in case it sheds light, my situation is actually that foo
is the get
method of an asyncio.Queue
instance. Therefore it may be enough to subclass and override this one-line method with a two-line one that does my desired lock acquisition first. Or monkeypatch the method on the instance. But this seems to be getting into ugly territory.
Updated after comment.
In general, when using locks you should hold them for the shortest duration possible .
Writing a subclass is probably the way to go if you need to use locks.
Your question doesn't contain enough detail to give other sensible recommendations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.