V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
whx20202
V2EX  ›  Python

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

  •  
  •   whx20202 · 2018-02-24 20:54:36 +08:00 · 4077 次点击
    这是一个创建于 2462 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    13 条回复    2018-02-26 15:49:58 +08:00
    ipwx
        1
    ipwx  
       2018-02-24 21:00:54 +08:00   ❤️ 1
    上策是修改你的程序架构,使得你不需要锁 key。

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

    a: object_a
    b: object_b

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

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

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

    用弱引用字典加双重判断和锁实现
    lolizeppelin
        9
    lolizeppelin  
       2018-02-25 01:25:13 +08:00 via Android
    更好的方式是修改这个字典用用专用线程做
    misaka19000
        10
    misaka19000  
       2018-02-25 09:27:53 +08:00 via Android
    @ipwx 请问这里为啥要素数个呢
    ipwx
        11
    ipwx  
       2018-02-25 11:41:26 +08:00
    @misaka19000 使得每个锁被选中的概率都是 1/N。非素数的话,每个锁的概率在整个整数域上会有一点不平均。
    mianju
        12
    mianju  
       2018-02-25 16:16:31 +08:00
    @misaka19000 hash 的常规操作吧,以前数据结构学散列表的时候经常这么用
    linhanqiu
        13
    linhanqiu  
       2018-02-26 15:49:58 +08:00
    @lolizeppelin 这个答案好
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2736 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 53ms · UTC 12:45 · PVG 20:45 · LAX 04:45 · JFK 07:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.