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