当前位置: 首页 > 面试题库 >

Java和C / C ++之间最快的(低延迟)进程间通信方法

柳玄裳
2023-03-14
问题内容

我有一个Java应用程序,通过TCP套接字连接到用C / C ++开发的“服务器”。

应用程序和服务器都在同一台机器上运行,这是一个Solaris机器(但我们正在考虑最终迁移到Linux)。交换的数据类型是简单的消息(登录,登录ACK,然后客户端要求某些内容,服务器答复)。每个消息大约300字节长。

当前,我们正在使用套接字,并且一切都很好,但是我正在寻找使用IPC方法交换数据(更快的延迟)的更快方法。

我一直在研究网络,并提出了以下技术的参考:

  • 共享内存
  • 管道
  • s列
  • 以及所谓的DMA(直接内存访问)

但是我找不到对它们各自性能的适当分析,也找不到如何在JAVA和C / C ++中实现它们(以便它们可以相互通信)的方法,但也许我可以想象如何做。

在这种情况下,任何人都可以评论每种方法的性能和可行性吗?任何指向有用的实现信息的指针/链接?

编辑/更新

在我到达这里的评论和答案之后,我找到了有关Unix Domain
Sockets的信息,该信息似乎是通过管道构建的,将为我节省整个TCP堆栈。它是特定于平台的,因此我计划使用JNI或juds或junixsocket对其进行测试。

下一个可能的步骤是直接实现管道,然后实现共享内存,尽管我已经被警告过额外的复杂性…

谢谢你的帮助


问题答案:

刚刚在我的Corei5 2.8GHz上测试了Java的延迟,仅发送/接收了单字节,仅产生了2个Java进程,而没有为任务集分配特定的CPU内核:

TCP         - 25 microseconds
Named pipes - 15 microseconds

现在明确指定核心掩码,例如 taskset 1 java Srvtaskset 2 java Cli

TCP, same cores:                      30 microseconds
TCP, explicit different cores:        22 microseconds
Named pipes, same core:               4-5 microseconds !!!!
Named pipes, taskset different cores: 7-8 microseconds !!!!

所以

TCP overhead is visible
scheduling overhead (or core caches?) is also the culprit

同时Thread.sleep(0)(如strace所示,导致执行单个sched_yield()Linux内核调用)需要0.3微秒-
因此,调度到单核的命名管道仍然有很多开销

一些共享内存的度量: 2009年9月14日– Solace
Systems今天宣布,使用共享内存传输,其统一消息平台API可以实现平均延迟小于700纳秒。

http://solacesystems.com/news/fastest-ipc-
messaging/

PS-第二天以内存映射文件的形式尝试了共享内存,如果可以接受繁忙的等待,我们可以将使用以下代码传递单个字节的延迟降低到0.3微秒:

MappedByteBuffer mem =
  new RandomAccessFile("/tmp/mapped.txt", "rw").getChannel()
  .map(FileChannel.MapMode.READ_WRITE, 0, 1);

while(true){
  while(mem.get(0)!=5) Thread.sleep(0); // waiting for client request
  mem.put(0, (byte)10); // sending the reply
}

注意:需要Thread.sleep(0),以便2个进程可以看到彼此的更改(我还不知道其他方法)。如果2个进程与任务集强制使用同一核心,则延迟变为1.5微秒-
这是上下文切换延迟

PPS-0.3微秒是个好数字!以下代码仅在执行原始字符串连接时,恰好需要0.1微秒:

int j=123456789;
String ret = "my-record-key-" + j  + "-in-db";

PPPS-希望这不是太多的话题,但是最后我尝试用增加静态volatile
int变量(JVM这样做时刷新CPU缓存)替换Thread.sleep(0)并获得-记录!- 72纳秒的延迟Java到Java进程通信

但是,当强制使用相同的CPU内核时,易失性递增的JVM永远不会相互控制,从而产生恰好10毫秒的延迟-Linux时间间隔似乎是5ms
…因此,只有在有备用内核时才应使用-否则sleep(0)更安全。



 类似资料:
  • 问题内容: 在以下情况下,实现C ++ / Java IPC的最佳方法是什么? 我有两个程序需要相互通信,一个是用C ++编写的,另一个是用Java编写的。两者都在同一台计算机上运行。 程序相互发送消息。消息通常很短(少于几百个字节),但是大小可能为100KB或更大。 不需要确认消息(即不需要像HTTP这样的请求/响应模型)。例如,C 程序向Java程序发送一条消息,而Java程序可以在以后的某个

  • 问题内容: Java上下文中的线程和进程之间有什么区别?用Java如何实现进程间通信和线程间通信?请给我指出一些现实生活中的例子。 问题答案: 根本的区别是线程位于相同的地址空间中,而进程位于不同的地址空间中。这意味着线程间通信是关于传递对对象的引用以及更改共享对象,而进程是关于传递对象的序列化副本。 在实践中,Java线程间通信可以实现为对共享对象进行简单的Java方法调用,并引入适当的同步。或

  • 本文向大家介绍c# 如何实现不同进程之间的通信,包括了c# 如何实现不同进程之间的通信的使用技巧和注意事项,需要的朋友参考一下   进程之间的通信是为了解决不同进程之间的数据传输问题,这样可以让不同程序交互数据。实现进程通信的方式:1、剪切板;2、COM;3、内存映射文件;4、WCF 1、剪切板Clipboard在进程间传送对象   剪切板是一个供应用程序使用的公有区域。在.NET中定一个了一个D

  • 最初,我在运行拓扑时只分配了1个executor给QueryNormalizer。执行潜伏期为8.952,处理潜伏期为12.857。 为了更快,我将QueryNormalizer中的执行程序数更改为4。执行延迟更改为197.616,处理延迟更改为59.132。 根据执行延迟的定义-元组在执行方法中花费的平均时间。execute方法可以在不发送元组的Ack的情况下完成。 此外,处理延迟是否应始终低于

  • 问题内容: 在Windows上,我们有一个C ++应用程序来启动Java进程。这两个应用程序需要彼此通信(通过xml片段)。 您将选择哪种进程间通信方法,为什么? 我们桌上的方法是:共享文件,管道和套接字(尽管我认为这有一些安全问题)。我愿意接受其他方法。 问题答案: 我不确定为什么您认为基于套接字的通信会带来安全隐患(使用SSL)。假设您具有明确定义的通信协议,这通常是一种非常好的方法,因为它与

  • 本文向大家介绍请问C++进程间怎么通信相关面试题,主要包含被问及请问C++进程间怎么通信时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 进程间通信主要包括管道、系统IPC(包括消息队列、信号量、信号、共享内存等)、以及套接字socket。 1.管道: 管道主要包括无名管道和命名管道:管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信