8

私は .Net (C++) のチームでアプリケーションを開発しており、Python や他の言語とやり取りするための COM インターフェイスを提供しています。

私たちが発見したのは、COM を介してデータをプッシュするのはかなり遅いということです。

私はいくつかの代替案を検討しました:

  • データをファイルにダンプし、com を介してファイル パスを送信する
  • mmap経由の共有メモリ?
  • ソケットを介して直接データをストリーミングしますか?

あなたの経験から、データを渡す最良の方法は何ですか?

4

4 に答える 4

9

Windowsのプロセス間通信メカニズムの範囲内で、パイプという名前のWindowsを使用した前向きな経験がありました。WindowsのオーバーラップIOとpywin32win32pipeのモジュールを使用します。

Win32とPythonについては、 Python ProgrammingOnWin32の本で詳しく知ることができます。

送信部分は単にに書き込みますr'\\.\pipe\mypipe'

リスナー(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 サービスまたはソケットを介した直接のいずれか。また、言語やプラットフォームに依存しないため、Python の部分を UNIX でホストすることに決めた場合、または突然 Java や PHP などの他の言語を使用したい場合に使用できます。

原則として、COM などの独自のプロトコル/アーキテクチャは、メリットよりも多くの制限を提供します。これが、そもそもオープン仕様が登場した理由です。

HTH

于 2008-11-13T09:50:30.823 に答える
2

+1 on the named pipes but I would also like to add that from your comments it seems that your application is very chatty. Every time you make a remote call no matter how fast the underlying transport is you have a fixed cost of marshaling the data and making a connection. You can save a huge amount of overhead if you change the addpoint(lat, long) method to a addpoints(point_array) method. The idea is similar to why we have database connection pools and http-keep-alive connections. The less actual calls you make the better. Your existing COM solution may even be good enough if you can just limit the number of calls you make over it.

于 2008-11-13T18:18:12.853 に答える
0

選択肢ごとにテストを設定してベンチマークを実行するのは、それほど複雑ではありません。注意することは、状況依存の経験的データに勝ります... :)

ああ、これをやれば、きっと多くの人がその結果に興味を持つでしょう。

于 2008-11-13T09:50:39.607 に答える