使用套接字进行进程间通信的限制是啥?

Posted

技术标签:

【中文标题】使用套接字进行进程间通信的限制是啥?【英文标题】:What are the limits of using sockets for Inter-Process Communication?使用套接字进行进程间通信的限制是什么? 【发布时间】:2010-11-26 17:38:44 【问题描述】:

我正在创建一个允许在 Firefox 中使用标准 ML (SML) 作为客户端编程语言的 Firefox 扩展。它的工作方式如下:

    该扩展程序启动 PolyML 进程(具有***交互式 shell 的 SML 编译器)。 然后在扩展和 PolyML 进程之间建立套接字通信。 从网页读取 SML 代码并通过套接字发送到 PolyML 进程进行评估。 然后该代码可能会使用我提供的库来处理 DOM。

以下是 DOM 库的实现方式:

    假设某人执行了一个 SML 函数 DOM.getElementById 此请求通过套接字转发到扩展程序,扩展程序在页面上执行 javascript 函数 getElementById 并将结果通过套接字发送回 PolyML 进程。

我的问题是,理论上,当涉及到套接字通信时,我应该期望在性能方面有什么限制?

我做了一些非常近似的分析,似乎使用扩展和 PolyML 之间的这个接口,我可以大约发送 2500 条消息/秒,平均大小为 70 字节/消息

为了把它放在更多的上下文中,假设我想使用 Canvas 元素在浏览器中绘制一些动画。如果我想达到 20fps,这意味着我需要在 0.05 秒内绘制每一帧,这意味着我每帧只能发送大约 125 条消息。这些消息对应于 JavaScript 函数调用。例如,下面的代码绘制了一条路径,并进行了 9 次 JavaScript 函数调用,对应于套接字通信中的 9 条消息。

val _ = Canvas.beginPath context;
val _ = Canvas.setFillStyle context fillColor;
val _ = Canvas.setStrokeStyle context fillColor;
val _ = Canvas.setLineWidth context size;
val _ = Canvas.moveTo context posx posy;
val _ = Canvas.lineTo context posx_new posy_new;
val _ = Canvas.stroke context;
val _ = Canvas.arc context posx_new posy_new (size/2.0) 0.0 6.28 true;
val _ = Canvas.fill context;

显然,JavaScript 的性能要好得多,我想你可以在这 0.05 秒内调用数千(数百)次 Canvas/DOM 函数来绘制框架。

所以,我想我的问题是,您是否有使用套接字通信进行非常快速的消息交换的经验。我想知道每秒 2500 条小消息(在这种情况下,对应于 150 KB/秒)似乎是正确的还是我做错了什么。

例如,一个怀疑是 Firefox 中的套接字实现(特别是通过 JavaScript 接口 https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIServerSocket 使用它)对于这种快速交互不是很好。例如,从套接字读取是通过事件循环机制完成的。那就是我依靠 Firefox.. 来通知我传入套接字消息的可用性,有时在发送消息和接收消息之间会有很大的延迟(例如 250 毫秒)(尽管这似乎只在 Firefox 忙于做其他事情,我对套接字通信的..理论..限制更感兴趣)

你有什么想法、想法、缺陷吗?您是否认为使用其他 IPC 机制会更好,例如管道,实现我从 C++ XPCOM 组件的通信,而不是从 JavaScript,到 C 的外部函数接口(JavaScript 和 PolyML 都有)?

(项目地址https://assembla.com/wiki/show/polymlext如果有人感兴趣的话)

【问题讨论】:

你在使用 TCP 吗? UDP?还是 UNIX 套接字?后者应该更快,因为操作系统不必关心网络错误。 不确定,我使用的是developer.mozilla.org/en/XPCOM_Interface_Reference/…。你知道这些是 TCP、UNIX 还是可配置的? 我也意识到瓶颈可能是 JSON 编码/解码,虽然我不记得那里使用了多少。 如果我正确理解源代码,nsIServerSocket 始终使用 AF_INET,即使是本地连接也是如此。 scottmoonen.com/tag/af_inet 给出了两者之间的比较:AF_UNIX 在 80.575200 秒内传输 100GB,对于 AF_INET+loopback 在 226.717520 秒内传输 100GB。 IHMO,TCP 足够快并且可以跨平台工作。 Windows AFAIK 上没有 UNIX 套接字。您最大的问题将是数据序列化。 【参考方案1】:

可以调整 TCP 以获得更高的吞吐量或更快的响应时间。为了获得更高的吞吐量,您需要将套接字缓冲区设置为更大的值。为了以较小的数据块获得良好的响应时间,您需要设置 TCP_NODELAY 套接字选项。环回上的 TCP 如果经过微调,它应该与任何 IPC 机制相同。较新的 Windows 操作系统对环回适配器进行了特殊优化,例如增加 MTU 大小等以使其更快。

【讨论】:

以上是关于使用套接字进行进程间通信的限制是啥?的主要内容,如果未能解决你的问题,请参考以下文章

进程间通信(IPC)——Unix域套接字 VS 网络套接字

资深程序员:深入Python进程间通信原理!

进程间的通信简单总结

在 Windows 服务和窗体应用程序之间使用套接字进行进程间通信

.Net 进程间通信

多路进程间通信