
我有多个线程会访问一个字典,会对某些 key 的值进行读,处理完了再写, 或者读了就不管了
我固然可以直接在字典读写这块的函数加 lock,但是感觉锁太重了
有没有办法能够让多个线程仅仅在同时访问,同一个 key 的时候再锁呢?
1 ipwx 2018-02-24 21:00:54 +08:00 上策是修改你的程序架构,使得你不需要锁 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 这个答案好 |