2014-09-19 80 views
1

使用下面的代碼似乎我可以使用multiprocessing.reduction很容易重建的子進程的套接字..扭曲 - 傳遞協議(和套接字句柄)對象扭子

import socket,os 
import multiprocessing 
from multiprocessing.reduction import reduce_handle, rebuild_handle 

client = socket.socket() 
client.connect(('google.com', 80)) 

rd = reduce_handle(client.fileno()) 

print "Parent: %s" % (os.getpid()) 

def test(x): 
     print "Child: %s" % (os.getpid()) 

     build = rebuild_handle(x) 
     rc = socket.fromfd(build, socket.AF_INET, socket.SOCK_STREAM) 
     rc.send('GET/HTTP/1.1\n\n') 
     print rc.recv(1024) 

p = multiprocessing.Process(target=test, args=(rd,)) 
p.start() 
p.join() 

我有一個扭曲遊戲服務器同時運行多個匹配。這些匹配可能包含多個玩家,每個玩家都有一個協議實例。我想要做的是在Twisted子流程池中分配匹配項,並讓這些池處理它們自己處理的匹配項的客戶端。看起來像讀取/寫入客戶端的數據,並將數據傳遞給子進程以及從子進程傳遞數據將是不必要的開銷。

協議保證是TCP實例,因此相信我能(如上面的代碼)降低這樣的插座:

rd = reduce_handle(myclient.transport.fileno()) 

一旦通過該數據以一個子通過查看扭曲源它看來我可以在子進程重建它現在這個樣子:

import socket 
from twisted.internet import reactor, tcp 
from multiprocessing.reduction import reduce_handle, rebuild_handle 

handle = rebuild_handle(rd) 
sock = socket.fromfd(handle, socket.AF_INET, socket.SOCK_STREAM) 
protocol = MyProtocol(...) 
transport = tcp.Connection(sock, protocol, reactor=reactor) 
protocol.transport = transport 

我只是想試試這個,但看到我不是超級熟悉的扭曲內部,即使這工作我真的不知道是什麼影響可能是。

誰能告訴我這是否看起來正確,它是否奏效?這是不明智的由於任何原因(我從來沒有見過扭曲的文檔或帖子中提到,即使它看起來很相關)?如果這有效,我應該警惕的任何事情?

在此先感謝。

回答

2

扭曲和多處理模塊彼此不兼容。如果代碼似乎有效,那只是偶然和偶然,未來的版本(可能沒有未來的多處理版本,但可能會有Twisted的期貨版本)可能會把這個好運轉爲不幸。

twisted.internet.tcp也不是一個偉大的模塊在應用程序中使用。這不完全是私人的,但你也不能依賴它總是與你的應用程序使用的反應堆一起工作。例如,IOCP反應器使用twisted.internet.iocpreactor.tcp來代替,而不會twisted.internet.tcp在所有的工作(我不希望它很可能你會使用IOCP反應器與此代碼和電抗器的扭曲船舶,其餘都使用twisted.internet.tcp但三階第三方反應堆可能不會和將來的Twisted版本可能會改變反應堆的實施方式)。

有你解決問題的兩個部分。一部分是在兩個進程之間傳輸文件描述符。另一部分是說服反應堆開始監視文件描述符並分派其事件。

Twisted使用multiprocessing.reduction的風險可能很小,因爲在該模塊中似乎沒有任何與流程管理有關的事情。相反,它只是酸洗插座。所以你可以繼續使用該方法傳遞你的文件描述符(如果你想避免在父進程中使用Twisted出於某種原因,你可能想要這樣做 - 我不確定,但它聽起來不是這樣就像這樣)。然而,這種替代是使用twisted.python.sendmsg超過UNIX套接字通過這些描述符 - 或者更好的是,使用該處理繁瑣sendmsg位給你更高級別的層:twisted.protocols.amp。 AMP支持一個參數類型,它是一個文件描述符,允許您在進程之間傳遞文件描述符(同樣,只能通過UNIX套接字),就像傳遞任何其他Python對象一樣。

至於第二部分,您可以使用reactor.adoptStreamConnection將已建立的TCP連接添加到反應器。這是一個你可以依賴的公共接口(只要反應堆實際上實現了它 - 不是所有的反應堆都這樣做:如果你想做一些優雅的退化或用戶友好的錯誤報告,你可以使用twisted.internet.interfaces.IReactorSocket.providedBy(reactor)反思反應堆) 。

+0

'multiprocessing.reduction'似乎是跨平臺的(Windows和unix),只要你能夠到達Twisted中的原始套接字,而sendmsg似乎是特定於unix的。這是一個直接的缺點,但是,我不是在Windows上工作。除此之外,這一切都是有道理的。謝謝! – Salis 2014-09-22 07:41:53