8

我正在与 .Net (C++) 团队一起开发一个应用程序,并提供一个 COM 接口来与 python 和其他语言进行交互。

我们发现通过 COM 推送数据非常缓慢。

我考虑了几种选择:

  • 将数据转储到文件并通过 com 发送文件路径
  • 通过mmap共享内存?
  • 直接通过套接字流数据?

根据您的经验,传递数据的最佳方式是什么?

4

4 回答 4

9

停留在 Windows 进程间通信机制中,我们在使用Windows 命名管道时获得了积极的经验。使用 Windows 重叠 IO 和win32pipe来自pywin32的模块。

你可以在Python Programming On Win32一书中了解很多关于 win32 和 python 的知识。

发送部分只是写入r'\\.\pipe\mypipe'.

listener( ovpipe) 对象持有一个事件句柄,等待带有可能其他事件的消息涉及调用win32event.WaitForMultipleObjects.

rc = win32event.WaitForMultipleObjects(
    eventlist,    # Objects to wait for.
    0,            # Wait for one object
    timeout)      # timeout in milli-seconds.

这是python重叠侦听器类的一部分:

import win32event
import pywintypes
import win32file
import win32pipe

class ovpipe:
"Overlapped I/O named pipe class"
def __init__(self):
    self.over=pywintypes.OVERLAPPED()
    evt=win32event.CreateEvent(None,1,0,None)
    self.over.hEvent=evt
    self.pname='mypipe'
    self.hpipe = win32pipe.CreateNamedPipe(
        r'\\.\pipe\mypipe',             # pipe name 
        win32pipe.PIPE_ACCESS_DUPLEX|   # read/write access
        win32file.FILE_FLAG_OVERLAPPED,
        win32pipe.PIPE_TYPE_MESSAGE|    # message-type pipe 
        win32pipe.PIPE_WAIT,            # blocking mode 
        1,                              # number of instances 
        512,                            # output buffer size 
        512,                            # input buffer size 
        2000,                           # client time-out
        None)                           # no security attributes
    self.buffer = win32file.AllocateReadBuffer(512)
    self.state='noconnected'
    self.chstate()

def execmsg(self):
    "Translate the received message"
    pass

def chstate(self):
    "Change the state of the pipe depending on current state"
    if self.state=='noconnected':
        win32pipe.ConnectNamedPipe(self.hpipe,self.over)
        self.state='connectwait'
        return -6

    elif self.state=='connectwait':
        j,self.strbuf=win32file.ReadFile(self.hpipe,self.buffer,self.over)
        self.state='readwait'
        return -6

    elif self.state=='readwait':
        size=win32file.GetOverlappedResult(self.hpipe,self.over,1)
        self.msg=self.strbuf[:size]
        ret=self.execmsg()
        self.state = 'noconnected'
        win32pipe.DisconnectNamedPipe(self.hpipe)
        return ret
于 2008-11-13T10:20:33.353 回答
2

XML/JSON 和一个 Web 服务或直接通过套接字。它也是独立于语言和平台的,所以如果你决定要在 UNIX 上托管 python 部分,或者如果你想突然使用 Java 或 PHP 或几乎任何其他语言,你可以。

作为一般规则,像 COM 这样的专有协议/架构提供的限制多于它们带来的好处。这就是为什么首先出现开放规范的原因。

高温高压

于 2008-11-13T09:50:30.823 回答
2

+1 在命名管道上,但我还想从您的评论中补充一点,您的应用程序似乎很健谈。每次进行远程调用时,无论底层传输速度有多快,您都有固定的数据编组和连接成本。如果将 addpoint(lat, long) 方法更改为 addpoints(point_array) 方法,则可以节省大量开销。这个想法类似于为什么我们有数据库连接池和 http-keep-alive 连接。你打的电话越少越好。如果您可以限制对它进行的调用次数,您现有的 COM 解决方案甚至可能已经足够好了。

于 2008-11-13T18:18:12.853 回答
0

为每个备选方案设置测试并进行基准测试应该不会太复杂。注意比上下文敏感的经验数据... :)

哦,如果你这样做,我相信很多人会对结果感兴趣。

于 2008-11-13T09:50:39.607 回答