我在进程和子进程之间使用 Twisted 的 Perspective Broker for RMI。
与其监听 TCP 套接字(例如通过传递 reactor.listenTCP()
PBServerFactory
实例)并让子进程连接到它,我宁愿更喜欢使用子进程的标准输入和标准输出。
我找到了 twisted.internet.stdio.StandardIO
,但如果这是要走的路,我不确定如何设置所有内容。
使用 PB over stdio 代替 TCP 是否可行?怎么办?
等等,为什么?
子进程用于运行不受信任的代码。它是沙盒化的,但需要能够以有限的方式与父进程进行通信。到目前为止,某种形式的 RMI 是特定用例的最干净的选择,而 PB 有一个看起来正确的访问模型。但是沙盒进程没有——也不应该需要——网络访问。 RMI 是它与外界的唯一通信方式,通过 stdin/stdout 进行管道传输似乎是一种干净的开展业务的方式。
但如果我没有以正确的方式解决这个问题,那也是一个完全有效的答案。
最佳答案
通过类似 stdio 的连接在父进程和子进程之间使用像 PB 这样的协议(protocol)有两个部分。一件在子进程中,使用文件描述符 0 和 1 与父进程通信。另一部分是父进程,使用与子进程的 0 和 1 相对应的任何文件描述符。
StandardIO
是第一 block 。您还需要第二部分 - 即 IReactorProcess.spawnProcess
。
但是,较新的端点 API 是访问此功能的更好方式。
端点的基础是客户端端点让您连接到服务器而不用关心连接是如何建立的,服务器端点让您接受来自客户端的连接不关心这些客户端是如何连接的。
有一个子进程客户端端点和一个标准输入输出服务器端点。这意味着您可以像这样编写您的客户端:
factory = PBClientFactory(...)
d = factory.getRootObject()
...
clientEndpoint.connect(factory)
你的服务器是这样的:
factory = PBServerFactory(...)
...
serverEndpoint.listen(factory)
现在您有了一个可以相互通信的客户端和服务器,但是您实际上还没有指定如何它们相互通信。可能是 TCP,也可能是 stdio。
然后您只需选择要使用的正确端点。坚持通过 stdio 进行通信的想法:
clientEndpoint = ProcessEndpoint(reactor, "/path/to/child", ("argv",), ...)
serverEndpoint = StandardIOEndpoint(reactor)
如果您稍后改变主意,那么切换到 - 比如说 - TCP 就像:
clientEndpoint = TCP4ClientEndpoint(reactor, "1.2.3.4", 12345)
serverEndpoint = TCP4ServerEndpoint(reactor, 12345)
或者您可以使用端点字符串描述的插件机制将其转换为配置:
clientEndpoint = clientFromString(reactor, options["client-endpoint"])
serverEndpoint = serverFromString(reactor, options["server-endpoint"])
其中 options["client-endpoint"]
和 options["server-endpoint"]
是像 "tcp:host=1.2.3.4 这样的字符串: port=12345"
和 "tcp:port=12345"
。
有关更多信息,请参阅 complete endpoints howto .
关于python - Perspective Broker 可以通过 stdio 而不是 TCP 使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16642374/