- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
两个进程(Java 和 Python)需要在我的应用程序中进行通信。我注意到套接字通信占用了 93% 的运行时间。为什么通讯这么慢?我应该寻找套接字通信的替代方法还是可以更快?
更新:我发现了一个简单的修复方法。由于某些未知原因,缓冲输出流似乎并未真正缓冲。因此,我现在将所有数据都放入客户端/服务器进程中的字符串缓冲区中。我在 flush 方法中将它写入套接字。
我仍然对使用共享内存在进程之间快速交换数据的示例感兴趣。
一些附加信息:
这是服务器端:
public class FastIPC{
public PrintWriter out;
BufferedReader in;
Socket socket = null;
ServerSocket serverSocket = null;
public FastIPC(int port) throws Exception{
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void send(String msg){
out.println(msg); // send price update to socket
}
public void flush(){
out.flush();
}
public String recv() throws Exception{
return in.readLine();
}
public static void main(String[] args){
int port = 32000;
try{
FastIPC fip = new FastIPC(port);
long start = new Date().getTime();
System.out.println("Connected.");
for (int i=0; i<50; i++){
for(int j=0; j<100; j++)
fip.send("+");
fip.send(".");
fip.flush();
String msg = fip.recv();
}
long stop = new Date().getTime();
System.out.println((double)(stop - start)/1000.);
}catch(Exception e){
System.exit(1);
}
}
}
客户端是:
import sys
import socket
class IPC(object):
def __init__(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.connect(("localhost", 32000))
self.fid = self.s.makefile() # file wrapper to read lines
self.listenLoop() # wait listening for updates from server
def listenLoop(self):
fid = self.fid
print "connected"
while True:
while True:
line = fid.readline()
if line[0]=='.':
break
fid.write('.\n')
fid.flush()
if __name__ == '__main__':
st = IPC()
最佳答案
您有多种选择。由于您使用的是 Linux,因此可以使用 UNIX 域套接字。或者,您可以将数据序列化为 ASCII 或 JSon 或其他格式,并通过管道、SHM(共享内存段)、消息队列、DBUS 或类似方式提供数据。值得考虑您拥有何种类型的数据,因为这些 IPC 机制具有不同的性能特征。有一个 draft USENIX paper对值得一读的各种权衡进行了很好的分析。
既然您说(在此答案的评论中)您更喜欢使用 SHM,那么这里有一些代码示例可以帮助您入门。使用 Python posix_ipc图书馆:
import posix_ipc # POSIX-specific IPC
import mmap # From Python stdlib
class SharedMemory(object):
"""Python interface to shared memory.
The create argument tells the object to create a new SHM object,
rather than attaching to an existing one.
"""
def __init__(self, name, size=posix_ipc.PAGE_SIZE, create=True):
self.name = name
self.size = size
if create:
memory = posix_ipc.SharedMemory(self.name, posix_ipc.O_CREX,
size=self.size)
else:
memory = posix_ipc.SharedMemory(self.name)
self.mapfile = mmap.mmap(memory.fd, memory.size)
os.close(memory.fd)
return
def put(self, item):
"""Put item in shared memory.
"""
# TODO: Deal with the case where len(item) > size(self.mapfile)
# TODO: Guard this method with a named semaphore
self.mapfile.seek(0)
pickle.dump(item, self.mapfile, protocol=2)
return
def get(self):
"""Get a Python object from shared memory.
"""
# TODO: Deal with the case where len(item) > size(self.mapfile)
# TODO: Guard this method with a named semaphore
self.mapfile.seek(0)
return pickle.load(self.mapfile)
def __del__(self):
try:
self.mapfile.close()
memory = posix_ipc.SharedMemory(self.name)
memory.unlink()
except:
pass
return
对于 Java 端,您想要创建相同的类,尽管我在评论中说了什么 JTux似乎提供了等效的功能,您需要的 API 在 UPosixIPC 中类。
下面的代码是您需要实现的事情的概要。但是,缺少一些东西——异常处理是显而易见的,还有一些标志(在 UConstant 中找到它们),并且您需要添加一个信号量来保护 put
/get
方法。但是,这应该会让您走上正确的轨道。请记住,mmap
或内存映射文件是一段 RAM 的类文件接口(interface)。因此,您可以像使用普通文件的 fd
一样使用它的文件描述符。
import jtux.*;
class SHM {
private String name;
private int size;
private long semaphore;
private long mapfile; // File descriptor for mmap file
/* Lookup flags and perms in your system docs */
public SHM(String name, int size, boolean create, int flags, int perms) {
this.name = name;
this.size = size;
int shm;
if (create) {
flags = flags | UConstant.O_CREAT;
shm = UPosixIPC.shm_open(name, flags, UConstant.O_RDWR);
} else {
shm = UPosixIPC.shm_open(name, flags, UConstant.O_RDWR);
}
this.mapfile = UPosixIPC.mmap(..., this.size, ..., flags, shm, 0);
return;
}
public void put(String item) {
UFile.lseek(this.mapfile(this.mapfile, 0, 0));
UFile.write(item.getBytes(), this.mapfile);
return;
}
public String get() {
UFile.lseek(this.mapfile(this.mapfile, 0, 0));
byte[] buffer = new byte[this.size];
UFile.read(this.mapfile, buffer, buffer.length);
return new String(buffer);
}
public void finalize() {
UPosix.shm_unlink(this.name);
UPosix.munmap(this.mapfile, this.size);
}
}
关于java - Java/Python 中的快速 IPC/Socket 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9250648/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!