我正在尝试使用Django缓存来实现锁定机制.在Celery官方site中,它声称Django缓存可以很好地工作.但是,以我的经验,它没有用.我的经验是,如果有多个线程/进程几乎在同一时间(接近0.003秒)获取锁,则所有线程/进程都将成功获取锁.对于晚于〜0.003秒获得锁定的其他线程,它将失败.
我是唯一一个经历过这件事的人吗?请尽可能纠正我.
def acquire(self, block = False, slp_int = 0.001):
while True:
added = cache.add(self.ln, 'true', self.timeout)
if added:
cache.add(self.ln + '_pid', self.pid, self.timeout)
return True
if block:
sleep(slp_int)
continue
else:
return False
# Set Django backend cache to localcache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/dev/shm/django_cache',
}
}
解决方法:
问题在于Django无法保证.add()的原子性. .add()是否实际上是原子的取决于您使用的后端.使用FileBasedCache时,.add()不是原子的:
def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
if self.has_key(key, version):
return False
self.set(key, value, timeout, version)
return True
Worker A执行.add()可以在self.has_key(…)之后但在self.set(…)之前被抢占.工人B一枪执行.add()将会成功设置密钥并返回True.当工作程序A恢复时,它还将设置密钥并返回True.
issue report表示您查看的示例代码假定后端为Memcached.如果您使用Memcached或支持原子.add()的后端,则它应该可以工作.