4

是否可以将 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 没有修补套接字,这就是它阻塞的原因。

4

1 回答 1

9

套接字已修补好,但您的代码还有其他问题。

首先,这

def fetch(url):
    g = gevent.spawn(urllib2.urlopen, url)
    return g.get().read()

是相同的

def fetch(url):
    return urllib2.urlopen(url).read()

你在这里产生了一个新的greenlet,然后阻止当前的greenlet,直到新的greenlet完成。它不会使事情并发。这与运行 urlopen 并等待它完成完全一样。

其次,为了利用gevent,必须同时运行多个轻量级线程(greenlet)。

然而,SimpleXMLRPCServer 被定义为

class SimpleXMLRPCServer(SocketServer.TCPServer,
                         SimpleXMLRPCDispatcher):

这意味着它一次只提供一个连接。

如果您创建自己的SimpleXMLRPCServer课程,但使用ThreadingTCPServer代替TCPServer,您应该能够从使用 gevent 中受益。

monkey.patch_all()补丁threading成为基于greenlet的,因此这样的服务器将为每个新连接生成一个新的greenlet。

于 2010-11-01T03:50:47.400 回答