2010-12-27 11 views
5

मैं यह पता लगाने की कोशिश कर रहा हूं कि मैं अपने कोड को मोड़ का उपयोग करके अधिक असीमित बना सकता हूं।घुमावदार स्थगित/कॉलबैक और एसिंक्रोनस निष्पादन

  • एक समारोह एक आस्थगित ऑब्जेक्ट
  • तो मैं तो deferred_obj.callback
  • के माध्यम से कॉलबैक की एक सूची
  • पहले कॉलबैक आस्थगित समारोह के बाद कहा जाएगा कुछ परिणाम प्रदान करता है जोड़ने के लिए, कॉलबैक की श्रृंखला में , पहले कॉलबैक डेटा के साथ कुछ करना और दूसरा कॉलबैक कॉल करेंगे
  • और आदि

हालांकि जंजीर कॉलबैक को असीमित नहीं माना जाएगा क्योंकि वे जंजीर हैं और इवेंट लूप उनमें से प्रत्येक को एक साथ फायरिंग जारी रखेगा, जब तक कि कोई और नहीं है, है ना?

हालांकि, अगर मेरे पास स्थगित ऑब्जेक्ट है, और मैं d.addCallback(deferred_obj.callback) में deferred_obj.callback के कॉलबैक के रूप में संलग्न करता हूं तो इसे एसिंक्रोनस माना जाएगा, क्योंकि deferred_obj डेटा की प्रतीक्षा कर रहा है, और उसके बाद विधि डेटा डेटा पर भी इंतजार कर रहा है, हालांकि एक बार जब मैं d.callback 'd' ऑब्जेक्ट डेटा को संसाधित करता है तो यह deferred_obj.callback को कॉल करता है, हालांकि इस ऑब्जेक्ट को स्थगित कर दिया गया है, इसलिए जंजीर कॉलबैक के मामले के विपरीत, यह अतुल्यकालिक रूप से निष्पादित होगा ... सही?

मेरा मानना ​​है कि मेरा सभी कोड गैर-अवरुद्ध है, इसका मतलब है कि जंजीर कॉलबैक असीमित नहीं हैं जबकि जंजीर स्थगित हैं, सही?

+6

कृपया इसे लें और टेक्स्ट की दीवार में इसका उपयोग करें: '...........' –

+0

जो कुछ भी इसका मतलब है:/ – mayotic

+0

उसका मतलब है कि आपका प्रश्न पढ़ने के लिए बहुत मुश्किल है क्योंकि यह दीवार है पाठ का, तो आपको कुछ और जगह का उपयोग करना चाहिए ... – Tommy

उत्तर

7

कॉलबैक कर रहे हैं (डिफ़ॉल्ट रूप से) तुल्यकालिक में कर सकते हैं। लेकिन, जैसा कि Twisted doc बताते हैं:

आप एक दूसरे पर प्रतीक्षा करने के लिए स्थगित की जरूरत है, तुम सब करने की जरूरत है वापसी एक एक विधि से स्थगित addCallbacks को जोड़ा गया है।

तो आप अपनी कॉलबैक श्रृंखला में कुछ एसिंक्रोनस प्रोसेसिंग करने के लिए इसका उपयोग कर सकते हैं। के ऐसा करते हैं:

from twisted.internet import reactor, defer 

def callback_func_2(result, previous_data): 
    # here we pass the result of the deferred down the callback chain 
    # (done synchronously) 
    print "calling function 1 on result:%s with previous result:%s" % (result, previous_data) 
    return result 

def callback_func(result): 
    #let's do some asynchronous stuff in this callback 
    # simple trick here is to return a deferred from a callback 
    # instead of the result itself. 
    # 
    # so we can do asynchronous stuff here, 
    # like firing something 1 second later and have 
    # another method processing the result 
    print "calling function 1 on result:%s" % result 
    d = defer.Deferred() 
    reactor.callLater(1, d.callback, "second callback") 
    d.addCallback(callback_func_2, result) 
    return d 

def do(): 
    d = defer.Deferred() 
    reactor.callLater(1, d.callback, "first callback") 
    d.addCallback(callback_func) 
    return d 

do() 
reactor.run() 
+0

हाँ उदाहरण के लिए धन्यवाद, मैं आपके प्रोग्राम में चित्रित एक समान मॉडल का उपयोग कर रहा हूं – mayotic

2

क्रमबद्ध करें, लेकिन इस प्रकार की घटना प्रसंस्करण में कोई सहमति नहीं है। जब तक कोड इवेंट लूप पर वापस न जाए तब तक कोई नया कॉलबैक नहीं बुलाया जाएगा। तो कॉलबैक की श्रृंखला तुल्यकालिक है। यह घटना लूप में केवल असीमित है।

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

+0

इसलिए यदि स्थगित ऑब्जेक्ट में कॉलबैक की एक श्रृंखला है, तो कोड पूरी घटना को पारित होने तक ईवेंट लूप पर वापस नहीं आएगा; हालांकि, अगर मैं स्थगित वस्तुओं का उपयोग करके इस श्रृंखला को तोड़ता हूं, तो मैं कोड को घटना लूप पर वापस जाने और अन्य घटनाओं की जांच करने की अनुमति देता हूं; सही बात? – mayotic

+0

हां, बिल्कुल। यह सामान्य पैटर्न है। डेटा के बड़े हिस्से को संसाधित करने के लिए आपको ईवेंट लूप में टाइमर पेश करना पड़ सकता है। – Keith

+0

ओई, ठीक है, आपको बहुत धन्यवाद: डी – mayotic

0

स्थगित करने से आपका कोड असीमित नहीं होता है।

import time 
from twisted.internet import defer 
from twisted.internet import reactor 

def blocking(duration, deferred): 
    print "start blocking" 
    time.sleep(duration) 
    print "finished blocking" 
    deferred.callback(True) 

def other_task(): 
    print "working..." 
    reactor.callLater(1, other_task) 

def finish(result): 
    print "stopping reactor in 2sec" 
    reactor.callLater(2, reactor.stop) 

def failed(reason): 
    print reason 
    print "stopping reactor in 2sec" 
    reactor.callLater(2, reactor.stop) 

def main(): 
    d = defer.Deferred() 
    d.addCallbacks(finish, failed) 
    reactor.callLater(0, blocking, 5, d) 

if __name__ == "__main__": 
    reactor.callLater(0, other_task) 
    main() 
    reactor.run() 

आप लंबे समय से चल है तुल्यकालिक कोड, आप deferToThread या इसे तोड़ने के एक सहकार्मी (twisted.internet.task) का उपयोग कम पुनरावृत्तियों

0

आप तो इस ढांचे की जाँच अपने कोड एक साफ दृष्टिकोण के साथ अधिक अतुल्यकालिक बनाना चाहते हैं:

https://github.com/iogf/untwisted

यह स्पष्ट प्रलेखन के साथ साफ कोड है। एसिंक्रोनस मॉडल से निपटने का दृष्टिकोण सीधा है।

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