python 协程为什么不用加锁_Python 异步编程 asyncio lock 如何让多个协程共享一把锁...

先上代码:

import asyncio

import aioredis

# redis 池

redis_pool = {

}

# redis 池读写锁

_lock = asyncio.Lock()

async def get_db(index:str="0"):

global redis_pool

await _lock.acquire() # 请求锁

db = redis_pool.get(index)

print(db)

if db is None:

specify_db = await aioredis.create_redis_pool("redis://localhost",db=int(index))

redis_pool.update({index:specify_db})

_lock.release() # 更新 redis 池完毕,释放锁

return specify_db

_lock.release() # 不需要生成 redis 连接,立即释放锁

return db

async def put_json(key:str,value:str,db_index:str="0",expire=-1):

db = await get_db(db_index)

await db.set(key,value,expire=expire)

async def test():

t1 = asyncio.create_task(get_db("0"))

t2 = asyncio.create_task(get_db("0"))

t3 = asyncio.create_task(get_db("0"))

t4 = asyncio.create_task(get_db("0"))

t5 = asyncio.create_task(get_db("0"))

task_list = [t1, t2, t3, t4, t5]

await asyncio.wait(task_list)

if __name__ == '__main__':

asyncio.get_event_loop().run_until_complete(test())

这是我构建了一个简易的 aioredis 连接池,如果单纯执行这个 test 的时候 lock 可以正确使用,但一旦其他异步代码通过 from import 调用put_json()那么get_db()就会抛出... got Future attached to a different loop,说lock.acquire()和 其他代码不再同一个事务循环中

而且查阅源码看到 asyncio.Lock()若不指定 loop 循环就会通过asyncio.get_event_loop()得到一个新循环,网上对于 asyncio.Lock 对象资料太少了。只有少量的 demo,demo 中是在 create_task 之前就创建好锁,然后参数传递给异步方法,这样做对 demo 有效,但对层次太多的代码很不友好

我现在的问题是我不想从 create_task()前就创建一把锁然后一直用参数传递到 get_db()中,因为这把锁只针对 redis_pool 的读写操作,其他代码根本不需要这把锁,还有有什么其他的办法可以调度协程对某个对象的读写吗

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值