2008-11-13 11 views
8

मैं नेट (सी ++) में एक टीम के साथ एक एप्लीकेशन विकसित कर रहा हूं और पाइथन और अन्य भाषाओं के साथ बातचीत करने के लिए एक COM इंटरफेस प्रदान करता हूं।विंडोज़ में पाइथन से दूसरे एप्लिकेशन में डेटा स्थानांतरित करने का सबसे अच्छा तरीका क्या है?

जो हमने पाया है वह है कि COM के माध्यम से डेटा को धक्का देना बहुत धीमा हो जाता है।

मैं माना जाता है कई विकल्प:

  • एक फाइल करने के लिए डेटा को डंप और mmap के माध्यम से
  • साझा मेमोरी कॉम के माध्यम से फ़ाइल पथ भेजने?
  • सीधे सॉकेट के माध्यम से डेटा स्ट्रीम करें?

अपने अनुभव से डेटा पास करने का सबसे अच्छा तरीका क्या है?

+0

क्या यह बड़ी मात्रा में डेटा है? क्या आप इसे क्रमबद्ध कर रहे हैं? डेटा की प्रकृति क्या है? –

+0

ज्यादातर मामलों में मूल रूप से लैट/लॉन पॉइंट डेटा। और फिलहाल यह COM के माध्यम से सीधे पारित किया गया है, कुछ ऐसा। एडपॉइंट (लैट, लॉन)। – monkut

उत्तर

9

विंडोज इंटरप्रोसेस संचार तंत्र के भीतर रहना, हमारे पास पाइप नामित विंडो का उपयोग करके सकारात्मक अनुभव था। विंडोज का उपयोग आईओ और मॉड्यूल pywin32 से ओवरलैप किया गया।

आप Python Programming On Win32 पुस्तक में Win32 और पायथन के बारे में बहुत कुछ सीख सकते हैं।

भेजने का हिस्सा बस r'\\.\pipe\mypipe' पर लिखता है।

एक श्रोता (ovpipe) ऑब्जेक्ट में एक ईवेंट हैंडल होता है, और संभावित अन्य घटनाओं के साथ एक संदेश की प्रतीक्षा में win32event.WaitForMultipleObjects पर कॉल करना शामिल है।

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

बढ़िया! धन्यवाद, मैंने नामित पाइपों के बारे में सुना है लेकिन कभी उनके साथ काम नहीं किया है, मुझे इसे देखना होगा! – monkut

+0

यह उत्तर अस्पष्ट है। क्या आप इन वर्गों का उपयोग कैसे कर सकते हैं? एक उदाहरण का स्वागत किया जाएगा। – MikeTeX

+0

@ माइकटेक्स कोड एक बड़े कार्यक्रम का सिर्फ एक स्निपेट है, उदाहरण नहीं। सिंक्रनाइज़ेशन को संभालने के लिए win32event.WaitForMultipleObjects() के साथ ईवेंट का उपयोग करके, आप नामित पाइप से (अनन्य) लिख सकते हैं और (पढ़ सकते हैं)। – gimel

2

एक्सएमएल/जेएसओएन और या तो एक वेब सेवा या सीधे सॉकेट के माध्यम से। यह भाषा और मंच भी स्वतंत्र है, इसलिए यदि आप तय करते हैं कि आप यूनिक्स पर पाइथन भाग को होस्ट करना चाहते हैं, या आप अचानक जावा या PHP का उपयोग करना चाहते हैं या आप कहीं भी किसी भी अन्य भाषा का उपयोग करना चाहते हैं।

एक सामान्य नियम स्वामित्व प्रोटोकॉल/COM जैसे आर्किटेक्चर के रूप में वे लाभ के मुकाबले अधिक प्रतिबंध प्रदान करते हैं। यही कारण है कि खुले विनिर्देश पहली जगह में दिखाई दिए।

HTH

0

यह भी अपने विकल्पों में से प्रत्येक के लिए एक परीक्षण की स्थापना की और एक बेंचमार्क करने के लिए जटिल नहीं होना चाहिए। नोटिंग संदर्भ संवेदनशील अनुभवजन्य डेटा धड़कता है ... :)

ओह, और यदि आप ऐसा करते हैं तो मुझे यकीन है कि बहुत से लोग परिणामों में रुचि रखते हैं।

+0

जब तक हम अधिक जानकारी नहीं जानते, यह एक बहुत ही समझदार उत्तर है। –

2

नामित पाइप पर +1 लेकिन मैं यह भी जोड़ने के लिए अपनी टिप्पणी से ऐसा लगता है कि है कि आपके आवेदन बहुत बातूनी है चाहते हैं:

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

यहाँ अजगर का हिस्सा श्रोता वर्ग ओवरलैप है। हर बार जब आप रिमोट कॉल करते हैं, इससे कोई फर्क नहीं पड़ता कि अंतर्निहित परिवहन कितनी तेज़ है, आपके पास डेटा को मार्शल करने और कनेक्शन बनाने की निश्चित लागत है। यदि आप ऐडपॉइंट (लैट, लार) विधि को एडपॉइंट्स (पॉइंट_एरे) विधि में बदलते हैं तो आप भारी मात्रा में ओवरहेड बचा सकते हैं। विचार समान है कि हमारे पास डेटाबेस कनेक्शन पूल और http-keep-live कनेक्शन क्यों हैं। कम वास्तविक कॉल आप बेहतर बनाते हैं। आपका मौजूदा COM समाधान भी पर्याप्त हो सकता है यदि आप उस पर किए गए कॉल की संख्या को सीमित कर सकते हैं।

+0

हमने इसमें कुछ देखा है, लेकिन बड़ी मात्रा में डेटा भेजते समय हमने स्मृति समस्याओं को मारा है। ब्लॉकों में डेटा भेजकर मेमोरी इश्यू को कुछ डिग्री तक कम किया जा सकता है। क्या कोई बेहतर तरीका है? – monkut