在下面的代碼中, test() 函式等待來自 UI 的請求,因為請求是以 JSON 形式接收的,它通過呼叫 handle() 函式為每個請求創建一個任務
async def test():
loop = asyncio.get_running_loop()
req = await receiver.recv_string()
logger.debug(f"Request received {req}")
req_json = json.loads(req)
logger.debug("Await create_task")
loop.create_task(handle(req_json))
async def handle(req_json_):
req_name = req_json_.get(req_name)
# acquire lock here based on req_name if request comes with different name acquire the lock
# but if the request comes with same name block the request
# untill the req for that name is completed if the request is already completed then acquire
# the lock with that name
logger.info(f"Request finished with req name {req_name} for action patch stack")
如何使用 asyncio 模塊或任何其他方式在 python 中實作這一點
uj5u.com熱心網友回復:
在我看來,您需要做的就是維護一個鎖字典,其鍵是變數給出的名稱req_name,其值是相應的鎖。如果該鍵reg_name不在字典中,則將為該鍵添加一個新鎖:
import asyncio
from collections import defaultdict
# dictionary of locks
locks = defaultdict(asyncio.Lock)
async def handle(req_json_):
req_name = req_json_.get(req_name)
# acquire lock here based on req_name if request comes with different name acquire the lock
# but if the request comes with same name block the request
# untill the req for that name is completed if the request is already completed then acquire
# the lock with that name
# Get lock from locks dictionary with name req_name. If it
# does not exit, then create a new lock and store it with key
# req_name and return it:
lock = locks[req_name]
async with lock:
# do whatever needs to be done:
...
logger.info(f"Request finished with req name {req_name} for action patch stack")
更新
如果您需要超時獲取鎖的嘗試,則創建一個協程,該協程獲取傳遞的鎖引數,并結合使用asyncio.wait_for合適的超時引數呼叫 :
import asyncio
from collections import defaultdict
async def acquire_lock(lock):
await lock.acquire()
# dictionary of locks
locks = defaultdict(asyncio.Lock)
async def handle(req_json_):
req_name = req_json_.get(req_name)
lock = locks[req_name]
# Try to acquire the lock but timeout after 1 second:
try:
await asyncio.wait_for(acquire_lock(lock), timeout=1.0)
except asyncio.TimeoutError:
# Here if the lockout could not be acquired:
...
else:
# Do whatever needs to be done
# The lock must now be explicitly released:
try:
...
logger.info(f"Request finished with req name {req_name} for action patch stack")
finally:
lock.release()
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/399896.html
