2010-12-08 24 views
18

मेरे पास एक प्रोग्राम है जिस पर मैं काम कर रहा हूं, वह दो नेटवर्क नेटवर्क स्रोतों से एक साथ पढ़ेगा। मैं थ्रेडिंग का उपयोग करने के बजाय एक असीमित दृष्टिकोण का प्रयास करना चाहता था। यह मैं नेतृत्व जो पुस्तकालय का उपयोग करने के आश्चर्य है ...कौन सा पायथन एसिंक पुस्तकालय मेरे कोड के लिए सबसे उपयुक्त होगा? Asyncore? मुड़?

मैं कुछ सरल उदाहरण कोड तरह का यह दर्शाता है कि क्या मेरा कार्यक्रम कर रही होगी के साथ आ गया है:

import sniffer 

def first(): 
    for station in sniffer.sniff_wifi(): 
     log(station.mac()) 

def second(): 
    for station in sniffer.sniff_ethernet(): 
     log(station.mac()) 

first() 
second() 

दो sniffer तरीकों देखो कुछ इस तरह:

def sniff_wifi(self): 

    while True: 
     yield mac_address 

while True पाश स्पष्ट रूप से उन्हें अवरुद्ध कर देता है।

मैं इसके लिए asyncore का उपयोग करना चाहता हूं क्योंकि यह मानक पुस्तकालय का हिस्सा है। कोई तीसरी पार्टी निर्भरता बोनस नहीं है। हालांकि, इसका मतलब यह नहीं है कि यदि आप अनुशंसा करते हैं तो मैं इसका उपयोग नहीं करूंगा ...

क्या मैं एसिंककोर के साथ क्या करने की कोशिश कर रहा हूं? यदि हां, तो क्या आप मुझे अपना उदाहरण कोड 'asyncore code' में परिवर्तित करने के तरीके दिखा सकते हैं? क्या आप किसी भी अच्छे एसिंककोर ट्यूटोरियल के बारे में जानते हैं?

उत्तर

3

असिनकोर अच्छा है लेकिन बहुत ही समृद्ध नहीं है, इसलिए जब आपका ऐप बढ़ता है तो आप बाद में समस्याओं में भाग ले सकते हैं। कहा जा रहा है, यह प्रोटोटाइप सामान के लिए बहुत अच्छा है। दृष्टिकोण काफी सरल है। आप कक्षा में कुछ घटनाओं को संभालने के तरीकों को परिभाषित करते हैं (जब संभव हो, जब लिखना संभव हो आदि) और उसके बाद asyncore.dispatcher (मुझे लगता है) वर्ग से उपclass।

official docs for the module साथ ही डौग हेलमैन के उत्कृष्ट PyMOTW article on it दस्तावेज़ों और उदाहरणों के लिए जांच करने के लिए अच्छे स्रोत हैं।

यदि आपका प्रोटोकॉल संवादात्मक है (उदा। इसे भेजें, प्राप्त करें), तो आप विचारों के लिए मानक लाइब्रेरी के साथ वितरित एसिंचैट मॉड्यूल भी देख सकते हैं।

ट्विस्ट एक और अधिक भारी कर्तव्य दृष्टिकोण है। मुझे यकीन है कि यह बड़ी परियोजनाओं के लिए बेहतर काम करेगा, यह कितना उपयोग किया जाता है लेकिन मैं और कुछ नहीं कह सकता क्योंकि मेरे पास इसका पहला हाथ अनुभव नहीं है।

+0

क्यों -1? ... –

+0

asyncore/asynchat केवल सॉकेट हैंडलिंग में बंधे होने पर ही उपयोगी होता प्रतीत होता है।मेरे कोड में, 'स्निफर' सभी सॉकेट सामान को संभालता है और परिणाम उत्पन्न करता है। मैं चाहता हूं कि एसिंककोर करना मेरा 'पहला' और 'दूसरा' फ़ंक्शंस चलाएं और मुझे 'स्निफर' रिटर्न डेटा के दौरान कॉलबैक जारी करने दें। यह मैं कैसे करूंगा? (मैंने आपको डाउनवोट नहीं किया है, बीटीडब्ल्यू) – dave

+1

एसिंककोर/एसिन्चैट आपको 'चयन' फ़ंक्शन कॉल के आसपास ऑब्जेक्ट ओरिएंटेड रैपर देता है (जो आम तौर पर सभी एसिंक चीजें बनती हैं)। 'select' फ़ाइल डिस्क्रिप्टर पर चल रहा है, इसलिए यह भी है कि asyncore/asynchat भी करता है। मेरे लिए कुछ काम करने योग्य बनाने के लिए मुझे कुछ मिनट दें। –

49

ट्विस्ट काफी हर संभव तरीके से बेहतर है। यह अधिक पोर्टेबल, अधिक फीचर, सरल, अधिक स्केलेबल, बेहतर बनाए रखा, बेहतर दस्तावेज है, और यह एक स्वादिष्ट आमलेट बना सकता है। Asyncore, सभी उद्देश्यों और उद्देश्यों के लिए, अप्रचलित है।

यह सब तरीकों से मुड़ एक संक्षिप्त उत्तर में बेहतर है (मैं कैसे एक छोटी उदाहरण में एक http/dns/ssh/smtp/pop/imap/irc/xmpp/process-spawning/multi-threading सर्वर प्रदर्शन कर सकता?) प्रदर्शित करने के लिए मुश्किल है, इसलिए बजाय मैं लोगों को सबसे आम गलत धारणाओं पर ध्यान केंद्रित किया जाएगा जो लोगों को मुड़ने के बारे में लगता है: यह एसिंककोर से कहीं अधिक जटिल या कठिन है।

चलो एक एसिंककोर उदाहरण के साथ शुरू करते हैं। पक्षपातपूर्ण प्रस्तुति से बचने के लिए, मैं किसी और से एक उदाहरण का उपयोग करूंगा जो अभी भी थोड़ा सा एसिंककोर पसंद करता है। यहां एक सरल एसिंककोर उदाहरण taken from Richard Jones' weblog है (ब्रेवटी के लिए टिप्पणियों के साथ)।

सबसे पहले, यहाँ सर्वर है:

import asyncore, socket 

class Server(asyncore.dispatcher): 
    def __init__(self, host, port): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.bind(('', port)) 
     self.listen(1) 

    def handle_accept(self): 
     socket, address = self.accept() 
     print 'Connection by', address 
     EchoHandler(socket) 

class EchoHandler(asyncore.dispatcher_with_send): 
    def handle_read(self): 
     self.out_buffer = self.recv(1024) 
     if not self.out_buffer: 
      self.close() 

s = Server('', 5007) 
asyncore.loop() 

और यहां ग्राहक है:

import asyncore, socket 

class Client(asyncore.dispatcher_with_send): 
    def __init__(self, host, port, message): 
     asyncore.dispatcher.__init__(self) 
     self.create_socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.connect((host, port)) 
     self.out_buffer = message 

    def handle_close(self): 
     self.close() 

    def handle_read(self): 
     print 'Received', self.recv(1024) 
     self.close() 

c = Client('', 5007, 'Hello, world') 
asyncore.loop() 

में कुछ अस्पष्ट मामलों है कि इस कोड सही तरीके से हैंडल नहीं करता हैं, लेकिन उन्हें समझा उबाऊ है और जटिल, और कोड पहले ही इस उत्तर को काफी लंबा बना चुका है।

अब, यहां कुछ कोड है जो मूल रूप से एक ही चीज़ है, ट्विस्ट के साथ। सबसे पहले, सर्वर:

from twisted.internet import reactor, protocol as p 

class Echo(p.Protocol): 
    def dataReceived(self, data): 
     self.transport.write(data) 

class EchoFactory(p.Factory): 
    def buildProtocol(self, addr): 
     print 'Connection by', addr 
     return Echo() 

reactor.listenTCP(5007, EchoFactory()) 
reactor.run() 

और अब, ग्राहक:

from twisted.internet import reactor, protocol as p 

class EchoClient(p.Protocol): 
    def connectionMade(self): 
     self.transport.write(self.factory.data) 

    def dataReceived(self, data): 
     print 'Received:', data 
     self.transport.loseConnection() 

class EchoClientFactory(p.ClientFactory): 
    protocol = EchoClient 
    def __init__(self, data): 
     self.data = data 

reactor.connectTCP('localhost', 5007, EchoClientFactory('Hello, world')) 
reactor.run() 

चीजें हैं जो मैं आपका ध्यान आकर्षित करना चाहते हैं के एक जोड़े हैं। सबसे पहले, मुड़कर उदाहरण 25% छोटा है, यहां तक ​​कि इस छोटे से कुछ के लिए भी। Asyncore के लिए 40 लाइनें, मुड़ के लिए केवल 30। चूंकि आपका प्रोटोकॉल अधिक जटिल हो जाता है, यह अंतर बड़ा और बड़ा हो जाएगा, क्योंकि आपको एसिंककोर के लिए अधिक से अधिक समर्थन कोड लिखना होगा जो आपके लिए मुड़कर प्रदान किया गया होगा।

दूसरा, ट्विस्ट पूर्ण अमूर्त प्रदान करता है। एसिंककोर उदाहरण के साथ, आपको वास्तविक नेटवर्किंग करने के लिए socket मॉड्यूल का उपयोग करना होगा; Asyncore केवल मल्टीप्लेक्सिंग प्रदान करता है। यदि आपको portable behavior on platforms such as Windows की आवश्यकता है तो यह एक समस्या है। इसका मतलब यह भी है कि एसिंककोर में अन्य प्लेटफार्मों पर एसिंक्रोनस उप-प्रक्रिया संचार करने के लिए सुविधाओं की पूरी कमी नहीं है; आप मनमाने ढंग से फाइल डिस्क्रिप्टर को select() विंडोज़ पर कॉल नहीं कर सकते हैं।

तीसरा, ट्विस्ट उदाहरण परिवहन तटस्थ है। Echo और EchoFactory और EchoClient और EchoClientFactory में से कोई भी किसी भी तरह से टीसीपी के लिए विशिष्ट नहीं है। आप इन कक्षाओं को पुस्तकालय में बना सकते हैं जिसे एसएसएच, या एसएसएल, या यूनिक्स सॉकेट, या पाइप के माध्यम से जोड़ा जा सकता है, केवल नीचे एक connectTCP/listenTCP कॉल को बदलकर। यह महत्वपूर्ण है, क्योंकि आपके प्रोटोकॉल तर्क में सीधे टीएलएस जैसे कुछ का समर्थन करना बहुत मुश्किल है। उदाहरण के लिए, टीएलएस में 'लिखना' निम्न स्तर पर 'पढ़ा' ट्रिगर करेगा। इसलिए, आपको इन चिंताओं को सही करने के लिए उन्हें अलग करने की आवश्यकता है।

अंत में, आपके उपयोग-मामले के लिए विशिष्ट, यदि आप सीधे मैक पते और ईथरनेट फ्रेम से निपट रहे हैं, तो ट्विस्ट में Twisted Pair, आईपी और ईथरनेट-स्तरीय नेटवर्किंग से निपटने के लिए निम्न स्तर की लाइब्रेरी है। यह मुड़ने का सबसे सक्रिय रूप से बनाए रखा हिस्सा नहीं है; कोड काफी पुराना है। लेकिन, यह काम करना चाहिए, और अगर ऐसा नहीं होता है तो हम इसमें कोई भी बग गंभीरता से लेंगे और (अंततः) देखेंगे कि वे तय हो गए हैं। जहां तक ​​मुझे पता है, एसिंककोर के लिए कोई तुलनात्मक लाइब्रेरी नहीं है, और इसमें निश्चित रूप से ऐसा कोई कोड नहीं है।

+5

यह मुड़ के लेखक से एक अच्छा परिचय होगा। – pyfunc

+1

+1। बहुत विस्तृत और बिंदु पर, लेकिन मुझे आपके से कम कुछ भी उम्मीद नहीं थी। :) –

+0

बेशक, मेरा जवाब अब प्रासंगिक नहीं है! – pyfunc

0

कर्ल को सभी दृष्टिकोणों में अवरुद्ध करने के लिए डिज़ाइन किया गया है और चयन का उपयोग करने से बचाता है जो एसिंक I/O के दौरान एक महंगा संचालन है। कम स्तर पर, कर्ल सबसे इष्टतम संभावित समाधानों का उपयोग कर रहा है, इस प्रकार इस तारीख तक कोई ढांचा नहीं है जो कर्ल से बेहतर प्रदर्शन करने में सक्षम है, हालांकि ढांचे हो सकते हैं जो समान प्रदर्शन दे सकते हैं।

कहा जा रहा है कि, अपने स्वयं के सॉकेट लिखने के बारे में कैसे? पाइथन में यह बहुत आसान है और एक बार जब आप जानते हैं कि आप क्या कर रहे हैं और अपने लक्ष्यों के साथ स्पष्ट हैं तो आपको अद्भुत प्रदर्शन दे सकते हैं।