python - 如何以原子方式将项目添加到 memcached 列表(在 Python 中)

标签 python multithreading memcached atomic

看下面我简单的 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/

相关文章:

memcached - 基于Memcache的消息队列?

python - 保存memcached数据后,在GAME上可以立即使用吗?

bash - 从更大的列表中创建 4 个元素的所有组合

python - python中的安全身份验证系统?

java - 你能调整 GAE 的内存缓存超时吗?

multithreading - 使用 applescriptobjc 实现 GDC

node.js - nodejs 服务器与 apache tomcat 服务器(App 服务器)有何不同?

python - 如何使用 paramiko 恢复文件传输

python - Matplotlib 错误栏,倾覆不起作用?

C# 图像,对象在其他地方使用错误