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