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

请教一个 gevent 初级问题,会有多线程问题吗?

  •  
  •   whx20202 · 2017-01-11 18:55:18 +08:00 · 4101 次点击
    这是一个创建于 2908 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如我有 1000 个网址 在一个 list 里面

    然后我起 10 个 gevent 协程去访问者 1000 个网址

    每次取一个网址,然后把这个网址从 list 里面删除

    访问完网址再去取一个

    请问这样有多线程之类的安全问题吗?

    9 条回复    2017-01-12 22:27:53 +08:00
    VicYu
        1
    VicYu  
       2017-01-11 19:03:37 +08:00
    虽然协程小弟办事靠谱

    也是找个大哥 epoll 来搞 io

    但是长者 GIL 还是保护了 list 线程安全
    RadishWind
        2
    RadishWind  
       2017-01-11 19:12:50 +08:00
    GIL 本身维护着一个全局锁来保证线程安全
    官方解释:
    In CPython, the global interpreter lock, or GIL,
    is a mutex that prevents multiple native threads from executing Python bytecodes at once.
    This lock is necessary mainly because CPython ’ s memory management is not thread-safe.
    (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)
    tabris17
        3
    tabris17  
       2017-01-11 19:19:21 +08:00 via iPhone
    协程是单线程,不会有多线程同步的问题
    ioiogoo
        4
    ioiogoo  
       2017-01-11 22:44:36 +08:00
    同一时间只有一个协程拥有运行权,不存在安全的问题
    xuboying
        5
    xuboying  
       2017-01-12 00:05:19 +08:00 via Android
    为何不分配好十等分,或者用 queue
    buckethead1
        6
    buckethead1  
       2017-01-12 03:08:17 +08:00
    同一个时刻只有一个协程在运行
    只有协程主动交出运行权,比如主动调用 gevent.sleep(),才会切换协程.
    所以不会在操作 list 的时候出错

    GIL 保证 bytecode 是线程安全的,比如 list.append()就是线程安全的,list[0] += 1 就不线程安全

    最后 你不确定的时候就加锁吧,反正都用 Python 了
    whx20202
        7
    whx20202  
    OP
       2017-01-12 07:23:13 +08:00 via iPhone
    @buckethead1 如果协程读数据库, gevent 会主动帮我切换吗
    mengskysama
        8
    mengskysama  
       2017-01-12 21:23:46 +08:00
    GIL 和这个问题是 2 个问题, http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm
    使用 gevent 的时候完全可以 if len(lstA): target=lstA.pop()不需要加锁。

    需要 gevent 里面使用同步试的数据库 driver 用 monkey patch 在 io 等待的时候线程交出运行权。
    psjay
        9
    psjay  
       2017-01-12 22:27:53 +08:00
    Gevent 协程只在发生 I/O 的时候进行切换,不用担心。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   978 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:59 · PVG 06:59 · LAX 14:59 · JFK 17:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.