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

标签 python sockets multiprocessing twisted

使用下面的代码,我似乎可以相当轻松地使用 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/

相关文章:

python - ValueError : Cannot convert <JIRA Status: name ='Close' , id ='6' > 到 Excel

python - Pandas:DataFrame.from_dict() 中的分隔符

python - 防止未网格 pcolor(mesh) 数据出现虚假水平线

c - TCP 套接字实现总是给出旧值

python - 如何在启用多进程的 Flask 应用程序中使用全局变量

python - 在多处理或多线程应用程序中保留 cpu 时间

python - 如何完全卸载使用 easy_install 安装的 pip?

Java-SocketException : Not a multicast address

java - Android 使用 Java 套接字崩溃

Python 多处理和 pathos : import error