2008-11-13 14 views
8

Tôi đang phát triển một ứng dụng có nhóm .Net (C++) và cung cấp giao diện COM để tương tác với python và các ngôn ngữ khác.Cách tốt nhất để chuyển dữ liệu từ python sang ứng dụng khác trong cửa sổ là gì?

Những gì chúng tôi nhận thấy là việc đẩy dữ liệu qua COM hóa ra khá chậm.

Tôi đã xem xét một số lựa chọn thay thế:

  • đổ dữ liệu vào một tập tin và gửi đường dẫn tập tin thông qua com
  • Memory Shared qua mmap?
  • Truyền dữ liệu trực tiếp qua ổ cắm?

Từ trải nghiệm của bạn cách tốt nhất để truyền dữ liệu là gì?

+0

Có số lượng dữ liệu khổng lồ không? Bạn đang sắp xếp nó? Bản chất của dữ liệu là gì? –

+0

Trong hầu hết các trường hợp, dữ liệu về điểm vĩ độ/dữ liệu điểm. Và tại thời điểm nó được chuyển trực tiếp thông qua COM, một cái gì đó như thế nào. AddPoint (lat, lon). – monkut

Trả lời

9

Giữ nguyên cơ chế giao tiếp giữa Windows, chúng tôi đã có trải nghiệm tích cực khi sử dụng các đường ống có tên là. Sử dụng Windows chồng chéo IO và mô-đun win32pipe từ pywin32.

Bạn có thể tìm hiểu nhiều về win32 và python trong sách Python Programming On Win32.

Phần gửi chỉ cần viết tới r'\\.\pipe\mypipe'.

Đối tượng nghe (ovpipe) giữ đối tượng xử lý sự kiện và đợi thông báo có các sự kiện khác có thể liên quan đến việc gọi win32event.WaitForMultipleObjects.

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

Dưới đây là một phần của python chồng chéo lớp nghe:

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 
+0

Tuyệt vời! Cảm ơn, tôi đã nghe nói về các đường ống được đặt tên nhưng chưa bao giờ làm việc với chúng, tôi sẽ phải kiểm tra nó! – monkut

+0

Câu trả lời này không rõ ràng. Bạn có thể giải thích cách sử dụng các lớp này không? một ví dụ sẽ được chào đón. – MikeTeX

+0

@MikeTex Mã chỉ là một đoạn của một chương trình lớn hơn, không phải là một ví dụ. Bạn có thể viết và (đọc) một cách không đồng bộ đến (từ) đường ống được đặt tên, sử dụng các sự kiện với win32event.WaitForMultipleObjects() để xử lý đồng bộ hóa. – gimel

2

XML/JSON và một Dịch vụ web hoặc trực tiếp thông qua một ổ cắm. Nó cũng là ngôn ngữ và nền tảng độc lập vì vậy nếu bạn quyết định bạn muốn lưu trữ phần python trên UNIX bạn có thể, hoặc nếu bạn muốn đột nhiên sử dụng Java hoặc PHP hoặc khá nhiều bất kỳ ngôn ngữ nào khác bạn có thể.

Theo nguyên tắc chung, các giao thức/kiến ​​trúc độc quyền như COM đưa ra nhiều hạn chế hơn so với lợi ích của chúng. Đây là lý do tại sao các thông số kỹ thuật mở xuất hiện ngay từ đầu.

HTH

0

Không quá phức tạp để thiết lập thử nghiệm cho từng lựa chọn thay thế của bạn và làm điểm chuẩn. Lưu ý nhịp đập dữ liệu thực nghiệm nhạy cảm theo ngữ cảnh ... :)

Ồ, và nếu bạn làm điều này, tôi chắc chắn sẽ có rất nhiều người quan tâm đến kết quả.

+0

Cho đến khi chúng tôi biết thêm thông tin, đây là một câu trả lời rất hợp lý. –

2

+1 trên các đường ống được đặt tên nhưng tôi cũng muốn nói thêm rằng từ bình luận của bạn có vẻ như ứng dụng của bạn là rất tán gẫu. Mỗi khi bạn thực hiện cuộc gọi từ xa bất kể tốc độ vận chuyển cơ bản là bao nhiêu thì bạn có một chi phí cố định để sửa đổi dữ liệu và tạo kết nối. Bạn có thể tiết kiệm một lượng lớn chi phí nếu bạn thay đổi phương thức addpoint (lat, long) thành phương thức addpoints (point_array). Ý tưởng này tương tự như lý do tại sao chúng tôi có các kết nối cơ sở dữ liệu và các kết nối http-keep-alive. Các cuộc gọi ít thực tế hơn bạn thực hiện tốt hơn. Giải pháp COM hiện tại của bạn thậm chí có thể đủ tốt nếu bạn chỉ có thể giới hạn số lượng cuộc gọi bạn thực hiện qua nó.

+0

Chúng tôi đã xem xét điều này, nhưng chúng tôi đã gặp phải vấn đề về bộ nhớ khi gửi một lượng lớn dữ liệu. Vấn đề bộ nhớ có thể được giảm nhẹ đến mức độ nào đó bằng cách gửi dữ liệu trong các khối. Có cách nào tốt hơn? – monkut