在Python中使用gevent和xmlrpclib
可以用Python的标准库xmlrpclib配合gevent吗?我现在尝试使用monkey.patch_all(),但没有成功。
from gevent import monkey
monkey.patch_all()
import gevent
import time
import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer
import urllib2
def fetch(url):
g = gevent.spawn(urllib2.urlopen, url)
return g.get().read()
def is_even(n):
return n%2 == 0
def req(url):
return fetch(url)
server = SimpleXMLRPCServer(("localhost", 8000))
print "Listening on port 8000..."
server.register_function(is_even, "is_even")
server.register_function(req, "req")
server.serve_forever()
urllib2.urlopen会阻塞服务器。看起来monkey.patch_all没有对socket进行补丁,所以它会阻塞。
1 个回答
9
这个socket修补得不错,但你的代码还有其他问题。
首先,这段代码
def fetch(url):
g = gevent.spawn(urllib2.urlopen, url)
return g.get().read()
和这段代码是一样的
def fetch(url):
return urllib2.urlopen(url).read()
你在这里创建了一个新的绿色线程(greenlet),但又把当前的线程给堵住了,等这个新的线程完成。这样并不能让事情并行处理。其实就跟直接运行urlopen然后等它完成是一样的。
其次,要想充分利用gevent,必须有多个轻量级线程(greenlet)同时运行。
但是,SimpleXMLRPCServer是这样定义的
class SimpleXMLRPCServer(SocketServer.TCPServer,
SimpleXMLRPCDispatcher):
这意味着它一次只能处理一个连接。
如果你自己创建一个SimpleXMLRPCServer
类,但用ThreadingTCPServer
替代TCPServer
,那么你就可以在这里利用gevent的优势。
monkey.patch_all()
会把threading
修补成基于greenlet的,这样每当有新连接时,服务器就会为每个新连接创建一个新的greenlet。