我有多个线程会访问一个字典,会对某些 key 的值进行读,处理完了再写, 或者读了就不管了
我固然可以直接在字典读写这块的函数加 lock,但是感觉锁太重了
有没有办法能够让多个线程仅仅在同时访问,同一个 key 的时候再锁呢?
1
ipwx 2018-02-24 21:00:54 +08:00 1
上策是修改你的程序架构,使得你不需要锁 key。
中策是预先创建 N 个锁(最好素数个),然后根据你的 key 算个哈希数值,模 N,锁对应的那个锁。 |
2
954880786 2018-02-24 21:03:07 +08:00
可以继承 UserDict 重写__getitem__方法
|
3
whx20202 OP @ipwx
你说这样行不行? 我的字典 { a: object_a b: object_b } 这两个对象我分别内置一个 lock = threading.Lock() 的实例,作为内置属性 然后获取到对象打算处理的时候,把对象的锁拿去来 acquire |
4
hahastudio 2018-02-24 21:07:31 +08:00
建一个 lock dict 然后每个 key 一把锁,修改 __getitem__ 之类的加锁?
话说,如果是 CPython 的话,是不是实现就是访问单个 object 就有全局锁? |
6
Philippa 2018-02-24 22:53:57 +08:00 via Android
我是你肯定会加一个队列 FIFO 算了
|
8
lolizeppelin 2018-02-25 01:19:17 +08:00 via Android
参考 openstack 的单例实现
用弱引用字典加双重判断和锁实现 |
9
lolizeppelin 2018-02-25 01:25:13 +08:00 via Android
更好的方式是修改这个字典用用专用线程做
|
10
misaka19000 2018-02-25 09:27:53 +08:00 via Android
@ipwx 请问这里为啥要素数个呢
|
11
ipwx 2018-02-25 11:41:26 +08:00
@misaka19000 使得每个锁被选中的概率都是 1/N。非素数的话,每个锁的概率在整个整数域上会有一点不平均。
|
12
mianju 2018-02-25 16:16:31 +08:00
@misaka19000 hash 的常规操作吧,以前数据结构学散列表的时候经常这么用
|
13
linhanqiu 2018-02-26 15:49:58 +08:00
@lolizeppelin 这个答案好
|