Python 能不能锁一个 key 或者一个 UUID?

2018-02-24 20:54:36 +08:00
 whx20202

我有多个线程会访问一个字典,会对某些 key 的值进行读,处理完了再写, 或者读了就不管了

我固然可以直接在字典读写这块的函数加 lock,但是感觉锁太重了

有没有办法能够让多个线程仅仅在同时访问,同一个 key 的时候再锁呢?

4078 次点击
所在节点    Python
13 条回复
ipwx
2018-02-24 21:00:54 +08:00
上策是修改你的程序架构,使得你不需要锁 key。

中策是预先创建 N 个锁(最好素数个),然后根据你的 key 算个哈希数值,模 N,锁对应的那个锁。
954880786
2018-02-24 21:03:07 +08:00
可以继承 UserDict 重写__getitem__方法
whx20202
2018-02-24 21:05:41 +08:00
@ipwx
你说这样行不行?
我的字典

a: object_a
b: object_b

这两个对象我分别内置一个 lock = threading.Lock() 的实例,作为内置属性

然后获取到对象打算处理的时候,把对象的锁拿去来 acquire
hahastudio
2018-02-24 21:07:31 +08:00
建一个 lock dict 然后每个 key 一把锁,修改 __getitem__ 之类的加锁?

话说,如果是 CPython 的话,是不是实现就是访问单个 object 就有全局锁?
ipwx
2018-02-24 21:20:55 +08:00
@whx20202 可以。Python 的字典本身的读写可以看做原子操作,所以锁对象我觉得够了。
Philippa
2018-02-24 22:53:57 +08:00
我是你肯定会加一个队列 FIFO 算了
lsylsy2
2018-02-24 23:03:45 +08:00
@ipwx 的中策很靠谱。
memcahed 就是这么做的。
lolizeppelin
2018-02-25 01:19:17 +08:00
参考 openstack 的单例实现

用弱引用字典加双重判断和锁实现
lolizeppelin
2018-02-25 01:25:13 +08:00
更好的方式是修改这个字典用用专用线程做
misaka19000
2018-02-25 09:27:53 +08:00
@ipwx 请问这里为啥要素数个呢
ipwx
2018-02-25 11:41:26 +08:00
@misaka19000 使得每个锁被选中的概率都是 1/N。非素数的话,每个锁的概率在整个整数域上会有一点不平均。
mianju
2018-02-25 16:16:31 +08:00
@misaka19000 hash 的常规操作吧,以前数据结构学散列表的时候经常这么用
linhanqiu
2018-02-26 15:49:58 +08:00
@lolizeppelin 这个答案好

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/432342

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX