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
yangva
V2EX  ›  Python

Python 的 pickle 或者 shelve 库为什么不能 dump 一个 gevent 协程对象

  •  
  •   yangva · 2020-08-16 13:13:57 +08:00 · 2064 次点击
    这是一个创建于 1592 天前的主题,其中的信息可能已经有所发展或是发生改变。

    报错如下:

    dEEH7n.png

    我进 pickle 库的源码看了,是用的 c 写的,所以代码被省略不可见了。 我网上搜了下,都没遇到我这个情况的(也可能我没找到),我试着把协程换成线程来 dump 也不行,线程报错是不能 dump 一个锁机制。

    场景需求是这样的:

    有个协程池,里面有多个协程对象在执行各自的任务(正在或者已完成),同时也有个 md5 映射表,表结构是{md5 值 1:gevent 协程对象 1,md5 值 2:gevent 协程对象 2,......}。

    要能在这一堆协程对象里通过映射表找出正在执行的指定的某个协程对象,状态已完成的则不考虑,然后可以在它运行中途时能 kill 掉。

    我本来打算用 pickle 库把这个 md5 表 dump 到数据库里,然后等需要结束某个协程对象时,再从数据库里 load 出来然后直接调用 kill 方法即可,结果就报上面的错。

    希望各位大佬能指点小弟一二,我个人感觉关键点就在怎么从一堆携程对象识别出哪个是目标,md5 映射表是我自己加的,不是固定需求,如果有更好的方案那肯定更好,我洗耳恭听,小弟在此感谢各位大佬了。

    9 条回复    2020-08-16 17:23:21 +08:00
    monsterxx03
        1
    monsterxx03  
       2020-08-16 13:22:33 +08:00 via Android   ❤️ 1
    greenlet 是不可以序列化的,不需要 md5,直接拿 greenlet.id 就行了,协程池在内存里维护 id 到 greenlet 的映射就行了,让协程池的程序暴露个接口,才能让外部来终止协程。
    yangva
        2
    yangva  
    OP
       2020-08-16 13:54:59 +08:00
    @monsterxx03 感谢大佬回复,我先试试
    yangva
        3
    yangva  
    OP
       2020-08-16 14:05:26 +08:00
    @monsterxx03 大佬,我刚试了下,有点尴尬的是,greenlet 没有 id 属性啊
    monsterxx03
        4
    monsterxx03  
       2020-08-16 14:28:45 +08:00 via Android
    啊,记错了,greenlet 的唯一 id 应该是要和它的 parent 拼起来的,简单点直接用 id()取一个标识也行
    cassidyhere
        5
    cassidyhere  
       2020-08-16 14:35:13 +08:00 via Android
    greenlet.getcurrent 。
    你的需求和 flask 的实现好像,可以看看 werkzeug.local 的源码
    yangva
        6
    yangva  
    OP
       2020-08-16 16:32:14 +08:00
    @monsterxx03 好吧,谢谢
    yangva
        7
    yangva  
    OP
       2020-08-16 16:32:28 +08:00
    @cassidyhere 好的,谢谢,我去看看
    abersheeran
        8
    abersheeran  
       2020-08-16 17:05:10 +08:00   ❤️ 1
    gevent 我不熟。不过 pickle 序列化对象是需要有对目标对象的支持的,Python 内置对象不用说,基本都可以。但是其他对象必须实现两个方法才能序列化反序列化的。

    https://stackoverflow.com/questions/1939058/simple-example-of-use-of-setstate-and-getstate
    yangva
        9
    yangva  
    OP
       2020-08-16 17:23:21 +08:00
    @abersheeran 好的,感谢大佬回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1018 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:39 · PVG 04:39 · LAX 12:39 · JFK 15:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.