簡體   English   中英

使用twisted的反應器進行Python多處理

[英]Python multiprocessing with twisted's reactor

我正在開發一個xmlrpc服務器,它必須周期性地執行某些任務。 我使用twisted作為xmlrpc服務的核心,但我遇到了一個小問題:

class cemeteryRPC(xmlrpc.XMLRPC):

    def __init__(self, dic):
        xmlrpc.XMLRPC.__init__(self)


    def xmlrpc_foo(self):
        return 1


    def cycle(self):
        print "Hello"
        time.sleep(3)


class cemeteryM( base ):

    def __init__(self, dic):   # dic is for cemetery
        multiprocessing.Process.__init__(self)
        self.cemRPC = cemeteryRPC()


    def run(self):
        # Start reactor on a second process
        reactor.listenTCP( c.PORT_XMLRPC, server.Site( self.cemRPC ) )
        p = multiprocessing.Process( target=reactor.run )
        p.start()

        while not self.exit.is_set():
            self.cemRPC.cycle()
            #p.join()


if __name__ == "__main__":

    import errno
    test = cemeteryM()
    test.start()

    # trying new method
    notintr = False
    while not notintr:
        try:
            test.join()
            notintr = True 
        except OSError, ose:
            if ose.errno != errno.EINTR:
                raise ose
        except KeyboardInterrupt:
            notintr = True

我應該如何加入這兩個過程,以便它們各自的連接不會阻塞?

(我對“加入”非常困惑。為什么它會阻止我用谷歌搜索但是找不到很多有用的解釋加入的用法。有人能解釋一下嗎?)

問候

你真的需要在一個單獨的進程中運行Twisted嗎? 這看起來很不尋常。

試着把Twisted的Reactor想象成你的主循環 - 並掛掉你需要的一切 - 而不是試圖將Twisted作為后台任務運行。

執行此類操作的更常規方法是使用Twisted的.callLater或將LoopingCall對象添加到Reactor。

例如

from twisted.web import xmlrpc, server
from twisted.internet import task
from twisted.internet import reactor

class Example(xmlrpc.XMLRPC):          
    def xmlrpc_add(self, a, b):
        return a + b

    def timer_event(self):
        print "one second"

r = Example()
m = task.LoopingCall(r.timer_event)
m.start(1.0)

reactor.listenTCP(7080, server.Site(r))
reactor.run()

嘿asdvawev - .join()在多處理中就像線程中的.join()一樣工作 - 它是一個阻塞調用,主線程運行等待工作者關閉。 如果工作者永遠不會關閉,那么.join()將永遠不會返回。 例如:

class myproc(Process):
    def run(self):
        while True:
            time.sleep(1)

調用run on this意味着join()永遠不會返回。 通常為了防止這種情況,我將使用傳遞給子進程的Event()對象來允許我發信號通知子進程何時退出:

class myproc(Process):
    def __init__(self, event):
        self.event = event
        Process.__init__(self)
    def run(self):
        while not self.event.is_set():
            time.sleep(1)

或者,如果您的工作被封裝在一個隊列中 - 您可以讓子進程在隊列中工作,直到它遇到一個sentinel(通常是隊列中的None條目),然后關閉。

這兩個建議意味着在調用.join()之前你可以發送set事件,或者插入sentinel,當調用join()時,進程將完成它的當前任務,然后正確退出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM