Twisted Pass Protocol(和套接字句柄)对象到Twisted子进程

2024-06-02 04:44:53 发布

您现在位置:Python中文网/ 问答频道 /正文

使用下面的代码,我似乎可以很容易地使用多处理.还原.. 在

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实例,所以我相信我可以(像上面的代码一样)这样减少套接字:

^{pr2}$

通过查看Twisted源将数据传递给子进程后,我似乎可以在子进程中重建它,如下所示:

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

我只想试试这个,但由于我对扭曲的内部结构不是很熟悉,即使这是可行的,我也不知道其中的含义。在

有谁能告诉我这看起来是否正确,是否可行?这是不是出于某种原因(我从未在Twisted文档或帖子中看到过它,尽管它似乎很相关)?如果这样行得通,我还有什么要提防的吗?在

提前谢谢。在


Tags: 数据fromimportclientreduce进程ostwisted
1条回答
网友
1楼 · 发布于 2024-06-02 04:44:53

Twisted和多处理模块彼此不兼容。如果代码看起来能正常工作,那只是运气和意外,而未来的版本(很可能没有多处理的未来版本,但可能会有Twisted的未来版本)可能会把这种好运变成厄运。在

twisted.internet.tcp也不是应用程序中使用的好模块。它并不完全是私有的,但也不能总是依赖它来处理应用程序使用的反应堆。例如,iocp reactor使用twisted.internet.iocpreactor.tcp,并且根本不会与twisted.internet.tcp一起工作(我不认为您很可能会使用iocp reactor和其他的reactor Twisted船使用twisted.internet.tcp,但是第三方反应堆可能不会,Twisted的未来版本可能会改变reactor的实现方式)。在

你要解决的问题有两个部分。一部分是在两个进程之间传输文件描述符。另一部分是说服reactor开始监视文件描述符并调度其事件。在

在Twisted中使用multiprocessing.reduction的风险可能很小,因为在该模块中似乎与流程管理没有任何关系。相反,它只是关于酸洗插座。因此,您可以继续使用该方法传递文件描述符(如果出于某种原因希望避免在父进程中使用Twisted,您可能会希望这样做—我不确定,但听起来并不是这样)。但是,另一种替代方法是使用twisted.python.sendmsg通过UNIX套接字传递这些描述符,或者更好的是,使用更高级的层来为您处理sendmsg位:twisted.protocols.amp。AMP支持一个参数类型,它是一个文件描述符,允许您在进程之间传递文件描述符(同样,只通过UNIX套接字),就像传递任何其他Python对象一样。在

至于第二部分,您可以使用reactor.adoptStreamConnection向reactor添加已经建立的TCP连接。这是一个您可以依赖的公共接口(只要reactor真正实现了它——并不是所有的reactor都这样做:如果您想进行某种优雅的降级或用户友好的错误报告,您可以使用twisted.internet.interfaces.IReactorSocket.providedBy(reactor)来反省reactor)。在

相关问题 更多 >