0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Kotlin協(xié)程實(shí)戰(zhàn)進(jìn)階之筑基篇3

jf_78858299 ? 來源:小余的自習(xí)室 ? 作者:蘇火火 ? 2023-05-30 16:26 ? 次閱讀

5.協(xié)程上下文

CoroutineContext表示協(xié)程上下文,是 Kotlin 協(xié)程的一個(gè)基本結(jié)構(gòu)單元。協(xié)程上下文主要承載著資源獲取,配置管理等工作,是執(zhí)行環(huán)境的通用數(shù)據(jù)資源的統(tǒng)一管理者。它有很多作用,包括攜帶參數(shù),攔截協(xié)程執(zhí)行等等。如何運(yùn)用協(xié)程上下文是至關(guān)重要的,以此來實(shí)現(xiàn)正確的線程行為、生命周期、異常以及調(diào)試。

協(xié)程使用以下幾種元素集定義協(xié)程的行為,它們均繼承自CoroutineContext

  • Job:??????????協(xié)程的句柄,對(duì)協(xié)程的控制和管理生命周期。
  • CoroutineName:??????協(xié)程的名稱,可用于調(diào)試。
  • CoroutineDispatcher:???調(diào)度器,確定協(xié)程在指定的線程來執(zhí)行。
  • CoroutineExceptionHandler:協(xié)程異常處理器,處理未捕獲的異常。這里暫不做深入分析,后面的文章會(huì)講解到,敬請(qǐng)期待。

協(xié)程上下文的數(shù)據(jù)結(jié)構(gòu)特征更加顯著,與List和Map非常類似。它包含用戶定義的一些數(shù)據(jù)集合,這些數(shù)據(jù)與協(xié)程密切相關(guān)。它是一個(gè)有索引Element 實(shí)例集合。每個(gè) element 在這個(gè)集合有一個(gè)唯一的Key。

//協(xié)程的持久上下文。它是[Element]實(shí)例的索引集,這個(gè)集合中的每個(gè)元素都有一個(gè)唯一的[Key]。
public interface CoroutineContext {
    //從這個(gè)上下文中返回帶有給定[key]的元素或null。
    public operator fun  get(key: Key<E>): E?

    //從[initial]值開始累加該上下文的項(xiàng),并從左到右應(yīng)用[operation]到當(dāng)前累加器值和該上下文的每個(gè)元素。
    public fun  fold(initial: R, operation: (R, Element) -> R): R

    //返回一個(gè)上下文,包含來自這個(gè)上下文的元素和來自其他[context]的元素。
    public operator fun plus(context: CoroutineContext): CoroutineContext

    //返回一個(gè)包含來自該上下文的元素的上下文,但不包含指定的[key]元素。
    public fun minusKey(key: Key<*>): CoroutineContext

    //[CoroutineContext]元素的鍵。[E]是帶有這個(gè)鍵的元素類型。
    public interface Key<E : Element>

    //[CoroutineContext]的一個(gè)元素。協(xié)程上下文的一個(gè)元素本身就是一個(gè)單例上下文。
    public interface Element : CoroutineContext {
        //這個(gè)協(xié)程上下文元素的key
        public val key: Key<*>

        public override operator fun  get(key: Key<E>): E?
    }
}
  • get(key):?可以通過key從這個(gè)上下文中獲取這個(gè)Element元素或者null。
  • fold():????提供遍歷當(dāng)前上下文中所有元素的能力。
  • plus(context):?顧名思義它是一個(gè)加法運(yùn)算,多個(gè)上下文元素可以通過+的形式整合成一個(gè)上下文返回。
  • minusKey(key):?與plus相反,減法運(yùn)算,刪除當(dāng)前上下文中指定key的元素,返回的是不包含指定
  • Element:????協(xié)程上下文的一個(gè)元素,本身就是一個(gè)單例上下文,里面有一個(gè)key,是這個(gè)元素的索引。

Element本身也實(shí)現(xiàn)了CoroutineContext 接口,像Int實(shí)現(xiàn)了List一樣,為什么元素本身也是集合呢?主要是Element它不會(huì)存放除它自己以外的數(shù)據(jù);Element屬性又有一個(gè)key,是協(xié)程上下文這個(gè)集合中元素的索引。這個(gè)索引在元素里面,說明元素一產(chǎn)生就找到自己的位置。

注意:協(xié)程上下文的內(nèi)部實(shí)現(xiàn)實(shí)際是一個(gè)單鏈表。

CoroutineName

//用戶指定的協(xié)程名稱。此名稱用于調(diào)試模式。
public data class CoroutineName(
    //定義協(xié)程的名字
    val name: String
) : AbstractCoroutineContextElement(CoroutineName) {
    //CoroutineName實(shí)例在協(xié)程上下文中的key
    public companion object Key : CoroutineContext.Key<CoroutineName>
}

CoroutineName是用戶用來指定的協(xié)程名稱的,用于方便調(diào)試和定位問題:

GlobalScope.launch(CoroutineName("GlobalScope")) {
    launch(CoroutineName("CoroutineA")) {//指定協(xié)程名稱
        val coroutineName = coroutineContext[CoroutineName]//獲取協(xié)程名稱
        print(coroutineName)
    }
}

協(xié)程內(nèi)部可以通過coroutineContext這個(gè)全局屬性直接獲取當(dāng)前協(xié)程的上下文。打印數(shù)據(jù)如下:

kotlin
復(fù)制代碼[DefaultDispatcher-worker-2] CoroutineName(CoroutineA)

上下文組合

從上面的協(xié)程創(chuàng)建的函數(shù)中可以看到,協(xié)程上下文的參數(shù)只有一個(gè),但是怎么傳遞多個(gè)上下文元素呢?CoroutineContext可以使用 " + " 運(yùn)算符進(jìn)行合并。由于CoroutineContext是由一組元素組成的,所以加號(hào)右側(cè)的元素會(huì)覆蓋加號(hào)左側(cè)的元素,進(jìn)而組成新創(chuàng)建的CoroutineContext。

GlobalScope.launch {
    //通過+號(hào)運(yùn)算添加多個(gè)上下文元素
    var context = CoroutineName("協(xié)程1") + Dispatchers.Main
    print("context == $context")

    context += Dispatchers.IO //添加重復(fù)Dispatchers元素,Dispatchers.IO 會(huì)替換 ispatchers.Main
    print("context == $context")

    val contextResult = context.minusKey(context[CoroutineName]!!.key)//移除CoroutineName元素
    print("contextResult == $contextResult")
}

注意:如果有重復(fù)的元素(key一致)則會(huì)右邊的會(huì)代替左邊的元素。打印數(shù)據(jù)如下:

context == [CoroutineName(協(xié)程1), Dispatchers.Main]
context == [CoroutineName(協(xié)程1), Dispatchers.IO]
contextResult == Dispatchers.IO

6.啟動(dòng)模式

CoroutineStart是一個(gè)枚舉類,為協(xié)程構(gòu)建器定義啟動(dòng)選項(xiàng)。在協(xié)程構(gòu)建的start參數(shù)中使用,

啟動(dòng)模式 含義 說明
DEFAULT 默認(rèn)啟動(dòng)模式,立即根據(jù)它的上下文調(diào)度協(xié)程的執(zhí)行 是立即調(diào)度,不是立即執(zhí)行,DEFAULT是餓漢式啟動(dòng),launch調(diào)用后,會(huì)立即進(jìn)入待調(diào)度狀態(tài),一旦調(diào)度器 OK 就可以開始執(zhí)行。如果協(xié)程在執(zhí)行前被取消,其將直接進(jìn)入取消響應(yīng)的狀態(tài)。
LAZY 懶啟動(dòng)模式,啟動(dòng)后并不會(huì)有任何調(diào)度行為,直到我們需要它執(zhí)行的時(shí)候才會(huì)產(chǎn)生調(diào)度 包括主動(dòng)調(diào)用該協(xié)程的start、join或者await等函數(shù)時(shí)才會(huì)開始調(diào)度,如果調(diào)度前就被取消,協(xié)程將直接進(jìn)入異常結(jié)束狀態(tài)。
ATOMIC 類似[DEFAULT],以一種不可取消的方式調(diào)度協(xié)程的執(zhí)行 雖然是立即調(diào)度,但其將調(diào)度和執(zhí)行兩個(gè)步驟合二為一了,就像它的名字一樣,其保證調(diào)度和執(zhí)行是原子操作,因此協(xié)程也一定會(huì)執(zhí)行。
UNDISPATCHED 類似[ATOMIC],立即執(zhí)行協(xié)程,直到它在當(dāng)前線程中的第一個(gè)掛起點(diǎn)。 是立即執(zhí)行,因此協(xié)程一定會(huì)執(zhí)行。即使協(xié)程已經(jīng)被取消,它也會(huì)開始執(zhí)行,但不同之處在于它在同一個(gè)線程中開始執(zhí)行。

這些啟動(dòng)模式的設(shè)計(jì)主要是為了應(yīng)對(duì)某些特殊的場景。業(yè)務(wù)開發(fā)實(shí)踐中通常使用DEFAULTLAZY這兩個(gè)啟動(dòng)模式就夠了。

7.suspend 掛起函數(shù)

suspend 是 Kotlin 協(xié)程最核心的關(guān)鍵字,使用suspend關(guān)鍵字修飾的函數(shù)叫作掛起函數(shù),掛起函數(shù)只能在協(xié)程體內(nèi)或者在其他掛起函數(shù)內(nèi)調(diào)用。否則 IDE 就會(huì)提示一個(gè)錯(cuò)誤:

Suspend function 'xxxx' should be called only from a coroutine or another suspend function

協(xié)程提供了一種避免阻塞線程并用更簡單、更可控的操作替代線程阻塞的方法:協(xié)程掛起和恢復(fù) 。協(xié)程在執(zhí)行到有suspend標(biāo)記的函數(shù)時(shí),當(dāng)前函數(shù)會(huì)被掛起(暫停),直到該掛起函數(shù)內(nèi)部邏輯完成,才會(huì)在掛起的地方resume恢復(fù)繼續(xù)執(zhí)行。

本質(zhì)上,掛起函數(shù)就是一個(gè)提醒作用,函數(shù)創(chuàng)建者給函數(shù)調(diào)用者的提醒,表示這是一個(gè)比較耗時(shí)的任務(wù),被創(chuàng)建者用suspend標(biāo)記函數(shù),調(diào)用者只需把掛起函數(shù)放在協(xié)程里面,協(xié)程會(huì)自動(dòng)調(diào)度處理,完成后在原來的位置恢復(fù)執(zhí)行。

注意:協(xié)程會(huì)在主線程中運(yùn)行,suspend 并不代表后臺(tái)執(zhí)行。

如果需要處理一個(gè)函數(shù),且這個(gè)函數(shù)在主線程上執(zhí)行太耗時(shí),但是又要保證這個(gè)函數(shù)是主線程安全的,那么您可以讓 Kotlin 協(xié)程在 Default 或 IO 調(diào)度器上執(zhí)行工作。在 Kotlin 中,所有協(xié)程都必須在調(diào)度器中運(yùn)行,即使它們是在主線程上運(yùn)行也是如此。協(xié)程可以 自行掛起(暫停) ,而調(diào)度器負(fù)責(zé)將其 恢復(fù) 。

掛起點(diǎn)

協(xié)程內(nèi)部掛起函數(shù)調(diào)用的地方稱為掛起點(diǎn) ,或者有下面這個(gè)標(biāo)識(shí)的表示這個(gè)就是掛起點(diǎn)。

掛起和恢復(fù)

協(xié)程在常規(guī)函數(shù)的基礎(chǔ)上添加了suspendresume兩項(xiàng)操作用于處理長時(shí)間運(yùn)行的任務(wù):

  • suspend:也稱掛起或暫停,用于掛起(暫停)執(zhí)行當(dāng)前協(xié)程,并保存所有局部變量。
  • resume:恢復(fù),用于讓已掛起(暫停)的協(xié)程從掛起(暫停)處恢復(fù)繼續(xù)執(zhí)行。

Kotlin 使用堆棧幀來管理要運(yùn)行哪個(gè)函數(shù)以及所有局部變量。 掛起 (暫停)協(xié)程時(shí),會(huì)復(fù)制并保存當(dāng)前的堆棧幀以供稍后使用,將信息保存到Continuation對(duì)象中。恢復(fù)協(xié)程時(shí),會(huì)將堆棧幀從其保存位置復(fù)制回來,對(duì)應(yīng)的Continuation通過調(diào)用resumeWith函數(shù)才會(huì)恢復(fù)協(xié)程的執(zhí)行,然后函數(shù)再次開始運(yùn)行。同時(shí)返回Result類型的成功或者異常的結(jié)果。

//Continuation接口表示掛起點(diǎn)之后的延續(xù),該掛起點(diǎn)返回類型為“T”的值。
public interface Continuation<in T> {
    //對(duì)應(yīng)這個(gè)Continuation的協(xié)程上下文
    public val context: CoroutineContext

    //恢復(fù)相應(yīng)協(xié)程的執(zhí)行,傳遞一個(gè)成功或失敗的結(jié)果作為最后一個(gè)掛起點(diǎn)的返回值。
    public fun resumeWith(result: Result<T>)
}

//將[value]作為最后一個(gè)掛起點(diǎn)的返回值,恢復(fù)相應(yīng)協(xié)程的執(zhí)行。
fun  Continuation.resume(value: T): Unit =
    resumeWith(Result.success(value))

//恢復(fù)相應(yīng)協(xié)程的執(zhí)行,以便在最后一個(gè)掛起點(diǎn)之后重新拋出[異常]。
fun  Continuation.resumeWithException(exception: Throwable): Unit =
    resumeWith(Result.failure(exception))

Kotlin 的 Continuation 類有一個(gè) resumeWith 函數(shù)可以接收 Result 類型的參數(shù)。在結(jié)果成功獲取時(shí),調(diào)用resumeWith(Result.success(value))或者調(diào)用拓展函數(shù)resume(value);出現(xiàn)異常時(shí),調(diào)用resumeWith(Result.failure(exception))或者調(diào)用拓展函數(shù)resumeWithException(exception),這就是 Continuation 的恢復(fù)調(diào)用。

Continuation類似于網(wǎng)絡(luò)請(qǐng)求回調(diào)Callback,也是一個(gè)請(qǐng)求成功和一個(gè)請(qǐng)求失敗的回調(diào):

public interface Callback {
  //請(qǐng)求失敗回調(diào)
  void onFailure(Call call, IOException e);

  //請(qǐng)求成功回調(diào)
  void onResponse(Call call, Response response) throws IOException;
}

注意:suspend不一定真的會(huì)掛起,如果只是提供了掛起的條件,但是協(xié)程沒有產(chǎn)生異步調(diào)用,那么協(xié)程還是不會(huì)被掛起。

那么協(xié)程是如何做到掛起和恢復(fù)?

suspend本質(zhì)(奪命七步)

一個(gè)掛起函數(shù)要掛起,那么它必定得有一個(gè)掛起點(diǎn),不然無法知道函數(shù)是否掛起,從哪掛起呢?

@GET("users/{login}")
suspend fun getUserSuspend(@Path("login") login: String): User

第一步 :將上面的掛起函數(shù)解析成字節(jié)碼:通過AS的工具欄中Tools->kotlin->show kotlin ByteCode

kotlin
復(fù)制代碼public abstract getUserSuspend(Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

上面的掛起函數(shù)本質(zhì)是這樣的,你會(huì)發(fā)現(xiàn)多了一個(gè)參數(shù),這個(gè)參數(shù)就是Continuation,也就是說調(diào)用掛起函數(shù)的時(shí)候需要傳遞一個(gè)Continuation給它,只是傳遞這個(gè)參數(shù)是由編譯器悄悄傳,而不是我們傳遞的。這就是掛起函數(shù)為什么只能在協(xié)程或者其他掛起函數(shù)中執(zhí)行,因?yàn)橹挥袙炱鸷瘮?shù)或者協(xié)程中才有Continuation。

第二步 :這里的Continuation參數(shù),其實(shí)它類似CallBack回調(diào)函數(shù),resumeWith()就是成功或者失敗回調(diào)的結(jié)果:

public interface Continuation<in T> {
    //協(xié)程上下文
    public val context: CoroutineContext

    //恢復(fù)相應(yīng)協(xié)程的執(zhí)行,傳遞一個(gè)成功或失敗的[result]作為最后一個(gè)掛起點(diǎn)的返回值。
    public fun resumeWith(result: Result<T>)
}

第三步 :但是它是從哪里傳進(jìn)來的呢?這個(gè)函數(shù)只能在協(xié)程或者掛起函數(shù)中執(zhí)行,說明Continuation很有可能是從協(xié)程充傳入來的,查看協(xié)程構(gòu)建的源碼:

public fun CoroutineScope.launch(): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}

第四步 :通過launch啟動(dòng)一個(gè)協(xié)程的時(shí)候,他通過coroutinestart方法啟動(dòng)協(xié)程:

public fun  start(start: CoroutineStart, receiver: R, block: suspend R.() -> T) {
    initParentJob()
    start(block, receiver, this)
}

第五步 :然后start方法里面調(diào)用了CoroutineStartinvoke,這個(gè)時(shí)候我們發(fā)現(xiàn)了Continuation:

public operator fun  invoke(block: suspend () -> T, completion: Continuation<T>): Unit =
    when (this) {
        DEFAULT -> block.startCoroutineCancellable(completion)
        ATOMIC -> block.startCoroutine(completion)
        UNDISPATCHED -> block.startCoroutineUndispatched(completion)
        LAZY -> Unit // will start lazily
    }

第六步 :而 Continuation通過block.startCoroutine(completion)傳入:

public fun  (suspend () -> T).startCoroutine(completion: Continuation

第七步 :最終回調(diào)到上面ContinuationresumeWith()恢復(fù)函數(shù)里面。這里可以看出協(xié)程體本身就是一個(gè)Continuation,這也就解釋了為什么必須要在協(xié)程內(nèi)調(diào)用suspend掛起函數(shù)了。(由于篇幅原因這里不做深入分析,后續(xù)的文章會(huì)分析這里,敬請(qǐng)期待!)

額外知識(shí)點(diǎn):在創(chuàng)建協(xié)程的底層源碼中,創(chuàng)建協(xié)程會(huì)返回一個(gè)Continuation實(shí)例,這個(gè)實(shí)例就是套了幾層馬甲的協(xié)程體,調(diào)用它的resume可以觸發(fā)協(xié)程的執(zhí)行。

任何一個(gè)協(xié)程體或者掛起函數(shù)中都隱含有一個(gè)Continuation實(shí)例,編譯器能夠?qū)@個(gè)實(shí)例進(jìn)行正確的傳遞,并將這個(gè)細(xì)節(jié)隱藏在協(xié)程的背后,讓我們的異步代碼看起來像同步代碼一樣。

@GET("users/{login}")
suspend fun getUserSuspend(@Path("login") login: String): User

GlobalScope.launch(Dispatchers.Main) {//開始協(xié)程:主線程
   val result = userApi.getUserSuspend("suming")//網(wǎng)絡(luò)請(qǐng)求(IO 線程)
   tv_name.text = result?.name //更新 UI(主線程)
}

launch()創(chuàng)建的這個(gè)協(xié)程,在執(zhí)行到某一個(gè)suspend掛起函數(shù)的時(shí)候,這個(gè)協(xié)程會(huì)被掛起,從當(dāng)前線程掛起。也就是說這個(gè)協(xié)程從正在執(zhí)行它的線程上脫離,這個(gè)協(xié)程在掛起函數(shù)指定的線程上繼續(xù)執(zhí)行,當(dāng)協(xié)程的任務(wù)完成時(shí),再resume恢復(fù)切換到原來的線程上繼續(xù)執(zhí)行。

在主線程進(jìn)行的 suspendresume 的兩個(gè)操作, 既實(shí)現(xiàn)了將耗時(shí)任務(wù)交由后臺(tái)線程完成,保障了主線程安全 ,也在不增加代碼復(fù)雜度和保證代碼可讀性的前提下做到不阻塞主線程的執(zhí)行??梢哉f,在 Android 平臺(tái)上協(xié)程主要就用來解決異步和切換線程這兩個(gè)問題。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2946

    瀏覽量

    104365
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3543

    瀏覽量

    93468
  • ui
    ui
    +關(guān)注

    關(guān)注

    0

    文章

    202

    瀏覽量

    21316
  • kotlin
    +關(guān)注

    關(guān)注

    0

    文章

    60

    瀏覽量

    4177
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    談?wù)?b class='flag-5'>協(xié)的那些事兒

    隨著異步編程的發(fā)展以及各種并發(fā)框架的普及,協(xié)作為一種異步編程規(guī)范在各類語言中地位逐步提高。我們不單單會(huì)在自己的程序中使用協(xié),各類框架如fastapi,aiohttp等也都是基于異步
    的頭像 發(fā)表于 01-26 11:36 ?1050次閱讀
    談?wù)?b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>的那些事兒

    Python中的多核CPU共享數(shù)據(jù)協(xié)詳解

    協(xié)又稱微線程,coroutne,協(xié)是一種用戶態(tài)的輕量級(jí)線程。通俗點(diǎn)講就是周末我在家里休息,假如我先洗漱,再煮飯,再下載電影看會(huì)很慢,用了協(xié)
    的頭像 發(fā)表于 12-07 10:23 ?6529次閱讀
    Python中的多核CPU共享數(shù)據(jù)<b class='flag-5'>之</b><b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>詳解

    Python自動(dòng)化運(yùn)維協(xié)函數(shù)賦值過程

    及同步的開銷(3)方便切換控制流,簡化編程模型(4)高并發(fā)+高擴(kuò)展性+低成本:一個(gè)CPU支持上萬的協(xié)都不是問題。所以很適合用于高并發(fā)處理。
    的頭像 發(fā)表于 03-18 11:22 ?3682次閱讀

    關(guān)于C++ 20協(xié)最全面詳解

    花了一兩周的時(shí)間后,我想寫寫 C++20 協(xié)的基本用法,因?yàn)?C++ 的協(xié)讓我感到很奇怪,寫一個(gè)協(xié)
    的頭像 發(fā)表于 04-12 11:10 ?1.3w次閱讀
    關(guān)于C++ 20<b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>最全面詳解

    Python后端項(xiàng)目的協(xié)是什么

    最近公司 Python 后端項(xiàng)目進(jìn)行重構(gòu),整個(gè)后端邏輯基本都變更為采用“異步”協(xié)的方式實(shí)現(xiàn)。看著滿屏幕經(jīng)過 async await(協(xié)在 Python 中的實(shí)現(xiàn))修飾的代碼,我頓時(shí)
    的頭像 發(fā)表于 09-23 14:38 ?1284次閱讀

    Python協(xié)與JavaScript協(xié)的對(duì)比及經(jīng)驗(yàn)技巧

    前言以前沒怎么接觸前端,對(duì) JavaScript 的異步操作不了解,現(xiàn)在有了點(diǎn)了解。一查發(fā)現(xiàn) Python 和 JavaScript 的協(xié)發(fā)展史簡直就是一毛一樣!這里大致做下橫向?qū)Ρ群涂偨Y(jié),便于
    的頭像 發(fā)表于 10-20 14:30 ?1821次閱讀

    使用channel控制協(xié)數(shù)量

    goroutine 是輕量級(jí)線程,調(diào)度由 Go 運(yùn)行時(shí)進(jìn)行管理的。Go 語言的并發(fā)控制主要使用關(guān)鍵字 go 開啟協(xié) goroutine。Go 協(xié)(Goroutine)之間通過信道(
    的頭像 發(fā)表于 09-19 15:06 ?1077次閱讀

    詳解Linux線程、線程與異步編程、協(xié)與異步

    協(xié)不是系統(tǒng)級(jí)線程,很多時(shí)候協(xié)被稱為“輕量級(jí)線程”、“微線程”、“纖(fiber)”等。簡單來說可以認(rèn)為
    的頭像 發(fā)表于 03-16 15:49 ?915次閱讀

    協(xié)的概念及協(xié)的掛起函數(shù)介紹

    協(xié)是一種輕量級(jí)的線程,它可以在單個(gè)線程中實(shí)現(xiàn)并發(fā)執(zhí)行。與線程不同,協(xié)不需要操作系統(tǒng)的上下文切換,因此可以更高效地使用系統(tǒng)資源。Kotlin
    的頭像 發(fā)表于 04-19 10:20 ?837次閱讀

    Kotlin協(xié)實(shí)戰(zhàn)進(jìn)階1

    協(xié)的概念在1958年就開始出現(xiàn)(比線程還早), 目前很多語言開始原生支, Java 沒有原生協(xié)但是大型公司都自己或者使用第三方庫來支持協(xié)
    的頭像 發(fā)表于 05-30 16:24 ?639次閱讀
    <b class='flag-5'>Kotlin</b><b class='flag-5'>協(xié)</b><b class='flag-5'>程</b><b class='flag-5'>實(shí)戰(zhàn)</b><b class='flag-5'>進(jìn)階</b><b class='flag-5'>之</b><b class='flag-5'>筑</b><b class='flag-5'>基</b><b class='flag-5'>篇</b>1

    Kotlin協(xié)實(shí)戰(zhàn)進(jìn)階2

    協(xié)的概念在1958年就開始出現(xiàn)(比線程還早), 目前很多語言開始原生支, Java 沒有原生協(xié)但是大型公司都自己或者使用第三方庫來支持協(xié)
    的頭像 發(fā)表于 05-30 16:25 ?648次閱讀
    <b class='flag-5'>Kotlin</b><b class='flag-5'>協(xié)</b><b class='flag-5'>程</b><b class='flag-5'>實(shí)戰(zhàn)</b><b class='flag-5'>進(jìn)階</b><b class='flag-5'>之</b><b class='flag-5'>筑</b><b class='flag-5'>基</b><b class='flag-5'>篇</b>2

    FreeRTOS任務(wù)與協(xié)介紹

    。 協(xié)是為那些資源很少的 MCU 準(zhǔn)備的,其開銷很小,但是 FreeRTOS 官方已經(jīng)不打算再更新協(xié)了。 任務(wù)特性: 1、簡單。 2、沒有使用限制。
    的頭像 發(fā)表于 09-28 11:02 ?906次閱讀

    C++20無棧協(xié)超輕量高性能異步庫開發(fā)實(shí)戰(zhàn)

    來了,c++標(biāo)準(zhǔn)委員會(huì)的謹(jǐn)慎態(tài)度也造就了c++20的給出來協(xié):“性能優(yōu)秀”,“開發(fā)靈活”和讓人勸退的“門檻之高”。 不過話說回來,c++從出身就注定了背負(fù)性能使命,他不是為簡單為
    的頭像 發(fā)表于 11-09 10:20 ?1068次閱讀

    協(xié)的實(shí)現(xiàn)與原理

    前言 協(xié)這個(gè)概念很久了,好多程序員是實(shí)現(xiàn)過這個(gè)組件的,網(wǎng)上關(guān)于協(xié)的文章,博客,論壇都是汗牛充棟,在知乎,github上面也有很多大牛寫了關(guān)于協(xié)
    的頭像 發(fā)表于 11-10 10:57 ?382次閱讀

    Linux線程、線程與異步編程、協(xié)與異步介紹

    協(xié)不是系統(tǒng)級(jí)線程,很多時(shí)候協(xié)被稱為“輕量級(jí)線程”、“微線程”、“纖(fiber)”等。簡單來說可以認(rèn)為
    的頭像 發(fā)表于 11-11 11:35 ?940次閱讀
    Linux線程、線程與異步編程、<b class='flag-5'>協(xié)</b><b class='flag-5'>程</b>與異步介紹