比如我有 1000 个网址 在一个 list 里面
然后我起 10 个 gevent 协程去访问者 1000 个网址
每次取一个网址,然后把这个网址从 list 里面删除
访问完网址再去取一个
请问这样有多线程之类的安全问题吗?
比如我有 1000 个网址 在一个 list 里面
然后我起 10 个 gevent 协程去访问者 1000 个网址
每次取一个网址,然后把这个网址从 list 里面删除
访问完网址再去取一个
请问这样有多线程之类的安全问题吗?
|
VicYuJan 11, 2017
1
虽然协程小弟办事靠谱
也是找个大哥 epoll 来搞 io 但是长者 GIL 还是保护了 list 线程安全 |
|
RadishWindJan 11, 2017
2
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.) |
|
tabris17Jan 11, 2017 via iPhone
3
协程是单线程,不会有多线程同步的问题
|
|
ioiogooJan 11, 2017
4
同一时间只有一个协程拥有运行权,不存在安全的问题
|
|
xuboyingJan 12, 2017 via Android
5
为何不分配好十等分,或者用 queue
|
|
buckethead1Jan 12, 2017
6
同一个时刻只有一个协程在运行
只有协程主动交出运行权,比如主动调用 gevent.sleep(),才会切换协程. 所以不会在操作 list 的时候出错 GIL 保证 bytecode 是线程安全的,比如 list.append()就是线程安全的,list[0] += 1 就不线程安全 最后 你不确定的时候就加锁吧,反正都用 Python 了 |
|
7
@buckethead1 如果协程读数据库, gevent 会主动帮我切换吗
|
|
mengskysamaJan 12, 2017
8
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 等待的时候线程交出运行权。 |
|
psjayJan 12, 2017
9
Gevent 协程只在发生 I/O 的时候进行切换,不用担心。
|