Gevent:在每个for循环迭代中yield是好习惯吗?
我之前使用的是Node.js,在那里有一些库,比如https://github.com/caolan/async,可以让我们在处理数组的时候异步进行,而不会阻塞事件循环。
我理解得对吗?在Gevent中,要实现同样的效果,可以在每次循环迭代时调用sleep(0)
吗?
在一个网络服务器中,这样做真的有必要吗?在解析数据库查询时,Python代码的阻塞时间(不是IO操作)是否可以忽略不计?
2 个回答
0
一般来说,不可以。
不过,如果处理整个数组所需的CPU时间太长,导致延迟变得不可接受,那你就应该把这整个任务交给另一个进程或者任务队列系统去处理。
每次你使用sleep(0)的时候,都会增加额外的开销(进程切换),所以这样反而会让情况变得更糟。
CPU密集型和IO密集型的任务在同一个进程里不太好搭配。
另外,如果你不需要很多同时连接,可以用预先分叉的服务器来替代gevent。
2
Gevent有一个叫做gevent.idle()
的功能,专门用来处理这个问题(不过这个功能似乎没有详细的说明:http://www.gevent.org/gevent.html#useful-general-functions)。
不过,如果你确定你的循环会进行一些耗时的、需要大量计算的处理,最好是把这些工作交给真正可以并行处理的工作者,比如使用multiprocessing
或者线程(Threads)。但要记住,你需要采取额外的措施,让这些方法能和Gevent很好地配合使用(据我所知)。