2017-12-18 119 views
6

में निलंबन कार्य का मतलब क्या है, मैं कोटलिन कोरोटाइन पढ़ रहा हूं और जानता हूं कि यह suspend फ़ंक्शन पर आधारित है। लेकिन suspend का क्या अर्थ है?कोटलिन कोरोटाइन

कोरआउट या फ़ंक्शन निलंबित हो जाता है?

https://kotlinlang.org/docs/reference/coroutines.html

से मूल रूप से, coroutines संगणना कि एक धागा

मैंने सुना है लोग अक्सर कहते हैं कि "समारोह निलंबित" को रोके बिना निलंबित किया जा सकता है। लेकिन मुझे लगता है कि यह कोरआउट है जो निलंबित हो जाता है क्योंकि यह काम खत्म होने की प्रतीक्षा कर रहा है? "निलंबित" आमतौर पर "संघर्ष समाप्त" का अर्थ है, इस मामले में coroutine निष्क्रिय है।

क्या हमें कहना चाहिए कि कोरआउट को निलंबित कर दिया गया है?

कौन सा कोरआउटिन निलंबित हो जाता है?

https://kotlinlang.org/docs/reference/coroutines.html

से सादृश्य जारी रखने के लिए इंतजार है() एक निलंबित समारोह (इसलिए भी एक async {} ब्लॉक के भीतर से प्रतिदेय) है कि एक coroutine जब तक कुछ गणना किया जाता है को निलंबित कर देता है और उसके रिटर्न हो सकता है परिणाम:

async { // Here I call it the outer async coroutine 
    ... 
    // Here I call computation the inner coroutine 
    val result = computation.await() 
    ... 
} 

यह कहते हैं, "है कि एक coroutine निलंबित कर देता है जब तक कुछ गणना किया जाता है", लेकिन एक हल्के धागे की तरह coroutine है। तो अगर कोरआउट को निलंबित कर दिया गया है, तो गणना कैसे की जा सकती है?

हम await देख computation पर कहा जाता है, तो यह async कि Deferred देता है, यह एक और coroutine शुरू कर सकते हैं

fun computation(): Deferred<Boolean> { 
    return async { 
     true 
    } 
} 

बोली कहना कि एक coroutine निलंबित कर देता है जिसका मतलब है कि हो सकता है। क्या इसका मतलब है suspend बाहरी async कोरआउट, या suspend आंतरिक computation कोरआउट?

suspend मतलब यह है कि जबकि बाहरी async coroutine खत्म करने के लिए आंतरिक computation coroutine के लिए (await) इंतज़ार कर रहा है, यह (बाहरी async coroutine) idles (इसलिए नाम को निलंबित) और थ्रेड पूल के लिए धागा देता है, और जब बच्चे computation कोरआउट खत्म होता है, यह (बाहरी async कोरआउट) उठता है, पूल से एक और धागा लेता है और जारी रहता है?

कारण मैं उल्लेख धागा है, क्योंकि https://kotlinlang.org/docs/tutorials/coroutines-basic-jvm.html

का धागा, जबकि coroutine इंतज़ार कर रहा है पूल में आ जाती है, और जब प्रतीक्षा किया जाता है, coroutine पूल में एक नि: शुल्क धागे पर शुरू

+0

https://medium.com/@elye।परियोजना/समझ-निलंबित-समारोह के- coroutines-de26b070c5ed – Elye

उत्तर

1

एक शिक्षण उपकरण मैं सुझाव है कि आप इस कोड के माध्यम से जाना है, जो बुनियादी तंत्र को इस तरह के async के रूप में सभी सुविधा निर्माणों अंतर्निहित को उजागर करता है के रूप में:

import kotlinx.coroutines.experimental.Unconfined 
import kotlinx.coroutines.experimental.launch 
import kotlin.coroutines.experimental.Continuation 
import kotlin.coroutines.experimental.suspendCoroutine 

var continuation: Continuation<Int>? = null 

fun main(args: Array<String>) { 
    launch(Unconfined) { 
     val a = a() 
     println("Result is $a") 
    } 
    10.downTo(0).forEach { 
     continuation!!.resume(it) 
    } 
} 

suspend fun a(): Int { 
    return b() 
} 

suspend fun b(): Int { 
    while (true) { 
     val i = suspendCoroutine<Int> { cont -> continuation = cont } 
     if (i == 0) { 
      return 0 
     } 
    } 
} 

Unconfined कोरआउट संदर्भ मूल रूप से कोरआउट संदर्भ के जादू को समाप्त करता है: आप बस launch ब्लॉक के अंदर कोड निष्पादित करना प्रारंभ करते हैं। क्या होता है इस प्रकार है:

  1. मूल्यांकन val a = a()
  2. यह चेन b() को, suspendCoroutine तक पहुंच गया।
  3. फ़ंक्शन b()suspendCoroutine पर पारित ब्लॉक निष्पादित करता है और फिर एक विशेष COROUTINE_SUSPENDED मान देता है। यह मान कोटलिन प्रोग्रामिंग मॉडल के माध्यम से देखने योग्य नहीं है, लेकिन संकलित जावा विधि यही है।
  4. फ़ंक्शन a(), इस वापसी मूल्य को देखते हुए, स्वयं भी इसे वापस कर देता है।
  5. launch ब्लॉक एक ही करता है और नियंत्रण अब launch मंगलाचरण के बाद लाइन रिटर्न: 10.downTo(0)...

ध्यान दें कि, इस बिंदु पर, आप एक ही प्रभाव है के रूप में यदि launch ब्लॉक और अंदर कोड अपने fun main कोड समवर्ती रूप से निष्पादित कर रहे हैं। यह बस होता है कि यह सब एक देशी धागे पर हो रहा है ताकि launch ब्लॉक "निलंबित" हो।

अब, forEach पाशन कोड के अंदर, इस कार्यक्रम continuation कि b() समारोह में लिखा था और 10 के मूल्य के साथ resumes इसे पढ़ता है। resume() इस तरह से कार्यान्वित किया गया है कि ऐसा होगा जैसे suspendCoroutine कॉल आपके द्वारा पारित मूल्य के साथ वापस लौटाया गया है। इसे i पर असाइन किया गया है और 0 के विरुद्ध चेक किया गया है। यदि यह शून्य नहीं है, तो while (true) लूप b() के अंदर चला जाता है, फिर से suspendCoroutine तक पहुंचता है, जिस बिंदु पर आपका resume() कॉल रिटर्न होता है, और अब आप forEach() में एक और लूपिंग चरण से गुजरते हैं। यह तब तक चलता है जब तक आप 0 के साथ फिर से शुरू नहीं करते हैं, तो println कथन चलाता है और कार्यक्रम पूरा हो जाता है।

उपरोक्त विश्लेषण आप महत्वपूर्ण अंतर्ज्ञान "एक coroutine निलंबित" नियंत्रण अंतरतम launch मंगलाचरण (या अधिक सामान्य रूप coroutine बिल्डर) करने के लिए वापस लौटने का मतलब है कि देना चाहिए।

कोरआउटिन संदर्भ की उपस्थिति इस तर्क को कम स्पष्ट करती है क्योंकि उनमें से अधिकतर तुरंत आपके कोड को दूसरे थ्रेड पर सबमिट करते हैं। उस स्थिति में उपर्युक्त कहानी उस अन्य धागे में होती है, और कोरआउट संदर्भ भी continuation ऑब्जेक्ट का प्रबंधन करता है ताकि वापसी मूल्य उपलब्ध होने पर इसे फिर से शुरू किया जा सके।