gpt4 book ai didi

python - Twisted - 将协议(protocol)(和套接字句柄)对象传递给 Twisted 子进程

转载 作者:行者123 更新时间:2023-12-01 05:01:53 26 4
gpt4 key购买 nike

使用下面的代码,我似乎可以相当轻松地使用 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 游戏服务器,可以同时运行多个比赛。这些比赛可能包含多个玩家,每个玩家都有一个协议(protocol)实例。我想做的是将匹配拆分到 Twisted 子进程池中,并让池处理它们自己正在处理的匹配的客户端。似乎读取/写入客户端数据并将该数据传入和传出子进程将是不必要的开销。

协议(protocol)保证是 TCP 实例,因此我相信我可以(如上面的代码)减少套接字,如下所示:

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

通过查看 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 的内部结构不是很熟悉,即使这可行,我也不知道这可能会产生什么影响。

谁能告诉我这看起来是否正确以及是否有效?出于某种原因,这是否是不可取的(我从未在 Twisted 文档或帖子中看到过它,尽管它看起来非常相关)?如果这有效,我应该警惕什么?

提前致谢。

最佳答案

Twisted 和多处理模块彼此不兼容。如果代码看起来有效,那只是运气和意外,两者的 future 版本(很可能没有多处理的 future 版本,但可能会有 Twisted 的 future 版本)可能会将这种好运气变成坏运气。 p>

twisted.internet.tcp也不是在您的应用程序中使用的好模块。它并不完全是私有(private)的,但您也不能依赖它始终与您的应用程序使用的 react 器一起工作。例如,iocp react 器使用twisted.internet.iocpreactor.tcp相反,对于 twisted.internet.tcp 根本不起作用(我不认为您很可能会在这段代码中使用 iocp react 器,并且 Twisted 附带的其余 react 器确实使用 twisted.internet.tcp 但第三方 react 器可能不会,并且 Twisted 的 future 版本可能会改变 react 器的方式已实现)。

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

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

对于第二部分,您可以使用reactor.adoptStreamConnection向 react 器添加已建立的TCP连接。 。这是一个您可以依赖的公共(public)接口(interface)(只要 react 器实际实现了它 - 并非所有反应器都这样做:如果您想做某种优雅的降级或用户友好的错误,您可以使用 twisted.internet.interfaces.IReactorSocket.providedBy(reactor) 内省(introspection) react 器报告)。

关于python - Twisted - 将协议(protocol)(和套接字句柄)对象传递给 Twisted 子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25932221/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com