4

geventでpythonの標準libsxmlrpclibを使用することは可能ですか?現在、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()

ここで新しいグリーンレットを生成していますが、新しいグリーンレットが完了するまで現在のグリーンレットをブロックしています。それは物事を並行させるものではありません。これは、urlopenを実行して終了するのを待つのとまったく同じです。

次に、geventを利用するには、同時に複数の軽量スレッド(グリーンレット)を実行する必要があります。

ただし、SimpleXMLRPCServerは次のように定義されます。

class SimpleXMLRPCServer(SocketServer.TCPServer,
                         SimpleXMLRPCDispatcher):

つまり、一度に1つの接続を提供します。

独自のSimpleXMLRPCServerクラスを作成し、ThreadingTCPServer代わりにを使用するTCPServer場合は、ここでgeventを使用することでメリットが得られるはずです。

monkey.patch_all()パッチthreadingをグリーンレットベースにするため、このようなサーバーは、新しい接続ごとに新しいグリーンレットを生成します。

于 2010-11-01T03:50:47.400 に答える