看下面我简单的 Python memcached 代码:
import memcache
memcache_client = memcache.Client(['127.0.0.1:11211'], debug=True)
key = "myList"
obj = ["A", "B", "C"]
memcache_client.set(key, obj)
现在,假设我想将元素“D”附加到缓存为 myList
的列表中,我该如何以原子方式执行此操作?
我知道这是错误的,因为它不是原子的:
memcache_client.set(key, memcache_client.get(key) + ["D"])
上面的语句包含竞争条件。如果另一个线程恰好在正确的时刻执行相同的指令,其中一个更新将被破坏。
我该如何解决这个竞争条件?如何以原子方式更新存储在 memcached 中的列表或字典?
最佳答案
下面是python客户端API对应的函数
https://cloud.google.com/appengine/docs/python/memcache/clientclass#Client_cas
还有一个 nice tutorial吉多·范·罗森 (Guido van Rossum)。希望他能比我更好地解释 python 的东西;)
在您的情况下,代码应如下所示:
memcache_client = memcache.Client(['127.0.0.1:11211'], debug=True)
key = "myList"
while True: # Retry loop, probably it should be limited to some reasonable retries
obj = memcache_client.gets(key)
assert obj is not None, 'Uninitialized object'
if memcache_client.cas(key, obj + ["D"]):
break
整个工作流程保持不变:首先获取一个值(带有一些绑定(bind)到键的内部信息),然后修改获取的值,然后尝试在内存缓存中更新它。唯一的区别是检查值(实际上是键/值对)是否没有从并行过程中同时更改。在后一种情况下,调用失败,您应该从头开始重试工作流。此外,如果您有一个多线程应用程序,那么每个 memcache_client 实例可能都应该是线程本地的。
另外不要忘记,对于本质上是“原子”的简单整数计数器,有 incr() 和 decr() 方法。
关于python - 如何以原子方式将项目添加到 memcached 列表(在 Python 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27414154/