如何处理Django-Channels使用者的竞争条件?

问题描述 投票:1回答:1

我正在使用django-channel实现服务,我已经对我的问题做了一些解释,但是您可以向下滚动至底部,在其中我提出问题,而忽略它们。

在此服务中,我使用异步缓存系统来提高服务的性能。写入此缓存会引发竞争条件问题。这是此缓存的两个主要功能

async def get_room_data_dict(self):
      data = await self.cache_client.get(self.key)
      return data

async def set_room_data_dict(self, room_data_dict):
      is_success = await self.cache_client.set(self.key, room_data_dict)
      return is_success

现在这是此方法的问题。

### coroutine 1 ###
room_data_dict = await cache_manager.get_room_data_dict()
# In the line below a context switch occurs and coroutine 2 continues to do some tasks
new_room_data_dict = await do_somthing(room_data_dict)
# coroutine 1 continue but room_data_dict is the old one and coroutine 1 going to save it so what coroutine 2 did is actually not applied
await cache_manager.set_room_data_dict(new_room_data_dict)

### coroutine 2 ###
# this coroutine continues without a context switch
room_data_dict = await cache_manager.get_room_data_dict()
new_room_data_dict = await do_somthing(room_data_dict)
await cache_manager.set_room_data_dict(new_room_data_dict)
# gets back to coroutine 1 and continues its code

现在,如果您仔细观察并进行了一些操作系统的培训,您会发现协程2对room_data_dict所做的更改实际上未应用。

为防止出现此问题,我要做的是这件事,我将更改以下功能

async def get_room_data_dict(self):
      await self.room_data_dict_semaphore.acquire()
      data = await self.cache_client.get(self.key)
      return data

async def set_room_data_dict(self, room_data_dict):
      is_success = await self.cache_client.set(self.key, room_data_dict)
      self.room_data_dict_semaphore.release()
      return is_success

[且仅当在组通道中共享代码中的信号量时,此方法才能解决我的问题。

所以这就是我要问的问题,如果您能回答任何一个问题,就可以解决我的问题:

  1. 如何在两个协程之间共享对象的实例(在我的问题中,在两个组通道之间)?
  2. 在python中,当您执行an_instance.str()时,会得到显示实例内存地址是什么的东西……我可以使用该地址获取该特定实例吗?
  3. 除了我的问题(使用信号灯)以外,其他解决我的问题的方法也将不胜感激。
python-3.x python-asyncio race-condition django-channels redis-cache
1个回答
0
投票

如何获取/释放外部范围(协程1)中的锁。

无论如何,各种锁定系统都允许您使用字符串键来标识锁定,以便可以从不同的作用域中获取/释放该锁定。您甚至可以使用python-redis-lock之类的分布式锁。

© www.soinside.com 2019 - 2024. All rights reserved.