python gevent pool_gevent

We can become blind by seeing each day as a similar one.

-- Paolo Coelho

教程

patch_all 不是一个好主意

gevent.monkey.patch_all() 给所有能打上 patch 的模块打上

gevent.monkey.patch_socket() 只给 socket 模块打上

我觉得最佳的方式是,只针对你需要的模块打 patch, 否则容易造成 gevent 的滥用。

gevent tutorial 称 monkeypatching 为 dark corners of Gevent.

当然,还有更精确的使用方法,例如:

gevent.sleep

gevent.select

参考:

http://www.gevent.org/gevent.monkey.html

http://sdiehl.github.com/gevent-tutorial/

并发下载示例

import gevent.monkey

gevent.monkey.patch_socket()

import gevent

import urllib2

import simplejson as json

def fetch(pid):

response = urllib2.urlopen('http://json-time.appspot.com/time.json')

result = response.read()

json_result = json.loads(result)

datetime = json_result['datetime']

print 'Process ', pid, datetime

return json_result['datetime']

def synchronous():

for i in range(1,10):

fetch(i)

def asynchronous():

threads = []

for i in range(1,10):

threads.append(gevent.spawn(fetch, i))

gevent.joinall(threads)

print 'Synchronous:'

synchronous()

print 'Asynchronous:'

asynchronous()

race condition

协程中避免使用全局变量来进行状态统计,或者结果收集。

若要收集结果,可以使用 value 属性来获取每个 greenlet 的返回值。

何时执行

gevent.spawn 时,协程已经开始执行。

gevent.joinall 只是用来等待所有协程执行完毕。

异常处理

注意,在协程外无法通过平常的异常捕获方式获取内部异常

# Exceptions raised in the Greenlet, stay inside the Greenlet.

try:

gevent.joinall([winner, loser])

except Exception as e:

print('This will never be reached')

但是,可以通过 exception 属性获得。

所以,每个协程内的异常最好自己包住,通过错误码返回给外面。

程序退出时,如何保证所有协程也退出

为了避免僵尸进程, 需要这样

import gevent

import signal

def run_forever():

gevent.sleep(1000)

if __name__ == '__main__':

gevent.signal(signal.SIGQUIT, gevent.shutdown)

thread = gevent.spawn(run_forever)

thread.join()

urllib2 超时处理

http://www.coder4.com/archives/2192

unpatch gevent patch

为什么要 unpatch ?

首先需要证明 patch 是一个邪恶的东西

a.py

import gevent.monkey

gevent.monkey.patch_socket()

import socket

print socket.socket #

b.py

import a

import socket

print socket.socket #

从运行结果看,a 模块的 patch 影响到了 b 模块的 socket 模块。

而实际上,我们并不是所有时候都需要 patch 后的 socket 行为,

"some tests rely on this patching, and some rely on not being patched."

如何避免这种影响呢?两种方法

只使用 gevent.socket, 不使用 patch

unpatch -> reload socket module

即将 b.py 修改为

import a

import socket

reload(socket)

print socket.socket #

参考:

http://stackoverflow.com/questions/10990151/gevent-monkey-unpatch/10991918#10991918

http://emptysquare.net/blog/undoing-gevents-monkey-patching/

如何限制并发的 greenlets

使用 gevent 的 pool

A pool is a structure designed for handling dynamic numbers of greenlets which

need to be concurrency-limited. This is often desirable in cases where one

wants to do many network or IO bound tasks in parallel.

在有大量 IO 并发的时候,需要限制并发量。同事限制在了 300. 具体根据机器性能,

测试决定。

示例代码:

https://github.com/sunzhongwei/test_gevent/blob/master/test_pool.py

gevent.subprocess

使用 gevent.subprocess 并发调用命令

https://github.com/sunzhongwei/config/blob/master/Templates/gevent_subprocess.py

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值