2015-08-21 5 views
7

मान लीजिए मैं एक लंबे चल समारोह है में एक अवरुद्ध समारोह कन्वर्ट करने के लिए:अजगर तूफान - उलझन में कैसे एक गैर अवरुद्ध समारोह

def long_running_function(): 
    result_future = Future() 
    result = 0 
    for i in xrange(500000): 
     result += i 
    result_future.set_result(result) 
    return result_future 

मैं एक हैंडलर में एक get समारोह है कि इसके बाद के संस्करण परिणाम के साथ उपयोगकर्ता प्रिंट है पाश के लिए एक की कि xrange में सभी संख्या जोड़ता है:

@gen.coroutine 
def get(self): 
    print "start" 

    self.future = long_running_function() 
    message = yield self.future 
    self.write(str(message)) 

    print "end" 

अगर मैं एक साथ दो वेब ब्राउज़र पर उपरोक्त कोड चलाने के लिए, मैं:

शुरू

अंत

शुरू

अंत

कौन सा अवरुद्ध किया जा रहा है। मेरी समझ से, @gen.coroutine और yield कथन प्राप्त कार्य में IOLoop को अवरुद्ध नहीं करता है, हालांकि, यदि कोई कार्य जो अवरोधक सह-रूटीन के अंदर है, तो यह IOLoop को अवरुद्ध करता है।

इसलिए मैंने जो कुछ किया है, वह long_running_function को कॉलबैक में बदलना है, और इसके बजाय yield gen.Task का उपयोग करना है।

@gen.coroutine 
def get(self): 
    print "start" 

    self.future = self.long_running_function 
    message = yield gen.Task(self.future, None) 
    self.write(str(message)) 

    print "end" 

def long_running_function(self, arguments, callback): 
    result = 0 
    for i in xrange(50000000): 
     result += i 
    return callback(result) 

यह भी कटौती नहीं करता है, यह मुझे देता है:

शुरू

अंत

शुरू

अंत

मैं में उन पर अमल करने धागे का उपयोग कर सकते समानांतर, लेकिन यह जाने का रास्ता प्रतीत नहीं होता है, क्योंकि मैं बहुत अधिक खुलता हूं विज्ञापन, और टोरनाडो के उपयोगकर्ता गाइड के अनुसार, यह महंगा हो सकता है।

लोग टोरनाडो के लिए एसिंक पुस्तकालय कैसे लिखते हैं?

उत्तर

6

यदि ब्लॉकिंग फ़ंक्शन सीपीयू-बाध्य है (जैसा कि आपके/xrange उदाहरण के लिए है), तो थ्रेड (या प्रक्रियाएं) इसे गैर-अवरुद्ध करने का एकमात्र तरीका है। आने वाले अनुरोध के प्रति धागा बनाना महंगा है, लेकिन सभी सीपीयू-बाध्य संचालन को संभालने के लिए एक छोटा थ्रेडपूल एक्स्सेलर बनाना नहीं है।

फ़ंक्शन का उपयोग किये बिना फ़ंक्शन को गैर-अवरुद्ध करने के लिए, फ़ंक्शन ईवेंट-संचालित होना चाहिए: यह कुछ बाहरी ईवेंट (जैसे नेटवर्क I/O) पर प्रतीक्षा कर रहा है ताकि वह उस घटना के दौरान जागृत हो सके होता है।

+0

मुझे लगता है कि आप सही हैं, लेकिन [कॉलिंग-अवरुद्ध-कार्य] (प्रेमी पी: //www.tornadoweb.org/en/stable/guide/coroutines.html#calling-blocking-functions) सीपीयू-बाउंड या इवेंट-संचालित का उल्लेख न करें, यह केवल इतना कहता है: "कॉल करने का सबसे आसान तरीका कोरआउटिन से अवरुद्ध करने का कार्य थ्रेडपूल एक्स्सेलर का उपयोग करना है, जो फ्यूचर्स लौटाता है जो कोरआउट के साथ संगत होते हैं " –

0

मैं वर्तमान में टोरनाडो और उसके वेबसाकेट फ़ंक्शन का उपयोग करके अपने सिमुलेशन प्रोग्राम के लिए एक वेब इंटरफ़ेस जोड़ने के लिए संघर्ष कर रहा हूं। मेरा सिमुलेशन प्रोग्राम कम्प्यूटेशनल गहन है, यानी, सीपीयू-बाउंड कार्य जैसा कि @ बेन-डर्नेल द्वारा कहा गया है, जिसे थ्रेड या प्रक्रिया का उपयोग करके कार्यान्वित किया जाना चाहिए।

कई जांच के बाद, मुझे लगता है कि इन संसाधनों से सहायता मिलेगी:

मैं अब इसी तरह के कार्यान्वयन कर रहा हूँ, और इस सवाल का जवाब जब अद्यतन करेगा मेरे पास और प्रगति है :)

संबंधित मुद्दे