<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

談談協程的那些事兒

jf_uPRfTJDa ? 來源: 移動Labs ? 2024-01-26 11:36 ? 次閱讀

Labs 導讀

隨著異步編程的發展以及各種并發框架的普及,協程作為一種異步編程規范在各類語言中地位逐步提高。我們不單單會在自己的程序中使用協程,各類框架如fastapi,aiohttp等也都是基于異步以及協程進行實現。那到底什么是協程?協程是怎么發展來的呢?本文將會對這些問題做一個深入淺出的介紹。

作者:李佳斌

單位:中國移動智慧家庭運營中心

本期Labs帶大家認識下

協程的那些事兒

Part 01進程,線程到協程

眾所周知,計算機操作系統中有兩個常見的概念:進程和線程。要講協程,我們先從這兩個基本概念入手。

? 進程:操作系統中每一個獨立允許的程序,都會占有操作系統分配的資源,是資源分配的基本單位。進程之間互不干涉,都只負責運行自己的指令,這就是進程。

? 線程:進程中的一個實體,是被系統獨立調度和CPU分派資源的基本單位,線程自己不擁有系統資源,只擁有一些運行時必不可少的資源,如自己的堆棧,程序計數器,寄存器數據等。一個進程可以有多個線程,各個線程共享進程所擁有的全部資源。

? 協程:協作的線程,也可以被稱作微線程,是一種用戶態的線程,協程的調度是由用戶主動完成的。代表了一種非搶占式的多任務并發的調度思想:協作式調度,即沒有優先級高低的區分。

- 對比

1、從內存占用,上下文切換內容,上下文切換過程等角度進行詳細對比。

8dc84184-bb65-11ee-8b88-92fbcf53809c.png

2、從包容關系上來說,一個進程至少包含一個線程,一個線程里面有0個或者多個協程,因此可歸納為如下圖:

8dec8972-bb65-11ee-8b88-92fbcf53809c.png

Part 02從異步編程說起

異步編程,也可以叫做并發編程,并發不同于并行:并行是物理上并行,至少要有2個CPU,兩個線程同時運行;而并發可以是單核,通過時間調度算法實現多任務調度,給人感覺是同時運行,實際上某一時刻只有一個線程在運行。異步編程能有效避免主線程被阻塞,特別是對于前端來說,如果主線程被阻塞,會導致APP無響應。常見的異步編程有:多線程,回調,Promise,響應式編程以及協程。

- 多線程

以發微博來舉例,發布操作可以簡單歸結為如下三個操作:

1、獲取用戶簽名數據prepareSubmit

2、攜帶簽名數據進行微博發布內容提交請求postSubmit

3、處理請求,響應結果processPost

最開始我們可能只有10個用戶,只需要啟動10個線程去操作,但是隨著用戶數增加到1000個,10000個,這個時候如果啟動10000個線程,由于每個線程至少會占用4M,10000個線程會占用39G的內存,對服務器的性能要求太高了,并且線程之間的切換也會占用大量的系統時間。因此這種方式只適用于線程之間沒有競爭關系,占用內存資源少,切對時延不敏感的情況。

8e0734f2-bb65-11ee-8b88-92fbcf53809c.png

- 回調

如果用異步回調的等方式解決上面發微博的問題,我們可以用如下代碼來解決,這種方式簡單易懂,使用范圍也很廣,幾乎所有的異步框架都用到了回調。但是也有很明顯的問題:

1、如果步驟很多就會出現嵌套地獄

2、對于異常的情況很難處理和傳遞

3、如果某一個步驟要等多個回調完成之后再進行收口操作,也很困難

8e1c9b4e-bb65-11ee-8b88-92fbcf53809c.png

- Promise

Promise是說對于一個耗時比較久的操作,程序給你一個承諾,保證不久之后會把結果告知你。它采用了鏈式編程模型,簡化了回調的異步操作,解決了嵌套地獄的問題,Promise有以下幾種狀態:

待定(pending): 初始狀態,既沒有被兌現,也沒有被拒絕。

兌現(fulfilled): 操作成功完成。

拒絕(rejected): 操作失敗。

發微博問題使用promise來解決如圖,必須等前置條件兌現之后才往后。

8e28f3c6-bb65-11ee-8b88-92fbcf53809c.png

Promise存在如下問題:

1、每一步的返回值類型都必須是 Promise,不能是實際的數據類型

2、錯誤處理變得復雜,不同階段產生的錯誤很難一路傳遞下去

3、不同階段之間共享數據困難

- 響應式編程

響應式編程(Reactive Extension簡稱Rx)的核心是將一切當作數據流,關注數據流的變換和流轉,描述數據輸入與輸出之間的關系,會實現數量眾多的擴展函數,這些函數只對輸入和輸出負責,因此可以很輕松的將函數分發到其他線程上實現異步調用。但Rx調試比較困難,學習成本較高,維護也不易。

- 協程

考慮到大部分互聯網請求都是IO密集型而不是CPU密集型,基本的流程都是:請求-少量計算-調用公共服務-大量讀寫數據庫-返回數據。因此IO密集型很容易發生讀寫阻塞,此時會進行線程切換,執行其他線程。但線程是寶貴的計算資源,因此我們希望線程不要阻塞,一直跑,不要切換上下文。針對這種需求,協程的優勢就出來了。協程執行如圖:

8e497d26-bb65-11ee-8b88-92fbcf53809c.png

★ 優點

1)協程的創建,銷毀和調度都發生在用戶態,避免CPU頻繁切換帶來的資源浪費

2)內存占用小,可以輕松創建幾十萬的協程

3)可讀性高,易維護,代碼基本等同于同步

4)通過結構化并發限制控制域,減少內存泄漏

Part 03種類劃分

- 按照調用棧分類

協程最關鍵的步驟就是暫停代碼和恢復代碼執行,實現方法主要基于棧和狀態機&閉包兩種。通過區分執行協程的時候是否可以在任意嵌套函數中被掛起,可以分為有棧協程和無棧協程,有棧協程可以被掛起,無棧協程不能被掛起。先看正常的函數棧操作:

8e64ef34-bb65-11ee-8b88-92fbcf53809c.png

有棧協程

協程實現的關鍵點就是如何保存、恢復和切換上下文,如果將一個函數當作協程,當有棧協程對函數的上下文進行保存,恢復和切換操作時,會對這個函數及其嵌套函數,棧針存儲的值,寄存器存儲的值進行快照操作,之后只需要對快照做,恢復和切換。

無棧協程

相比于有棧協程,無棧協程在不改變調用棧的情況下采用了類似狀態機和閉包的方式來存儲暫停點的代碼信息。在不改變函數調用棧的情況下,我們也不可能在任意一個嵌套函數中掛起協程,這也是無棧協程的特點,同時由于不需要切換棧幀,無棧協程的性能比有棧協程還要高一點。

- 按照調度方式分類

協程的暫停和恢復涉及到控制權的轉移,可以分為非對稱協程和對稱協程。

非對稱協程

非對稱協程通過暫停和繼續兩個指令進行控制權轉移,暫停之后控制權就會轉移給繼續指令所在的協程,因此控制權的轉移存在較弱的調用方和被調用方的關系。

對稱協程

對稱協程只有一個繼續指令,各協程之間地位是平等的,繼續指令執行之后,控制權就會在多個協程之間流轉。

Part 04總結

在高并發、高請求當道的今天,合理利用協程勢必會提升我們的系統性能和用戶體驗。當我們的業務操作或者網絡請求面臨大量IO時,我們可以考慮采用協程替換線程,能夠幫助我們的應用降低系統內存占用,同時也減少了系統切換開銷,提升系統性能。然而協程雖然很強大,但是也不要過度使用,協程只有和異步IO結合起來才能發揮出最大的威力。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10491

    瀏覽量

    207041
  • 操作系統
    +關注

    關注

    37

    文章

    6333

    瀏覽量

    122023
  • 編程
    +關注

    關注

    88

    文章

    3444

    瀏覽量

    92600
  • 線程
    +關注

    關注

    0

    文章

    494

    瀏覽量

    19522

原文標題:關于協程,你了解多少?

文章出處:【微信號:5G通信,微信公眾號:5G通信】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Linux內存的那些事兒

    CPU、IO、磁盤、內存,可以說是影響計算機性能的幾大關鍵因素。今天,我們就來探究一下內存的那些事兒。
    發表于 09-08 14:16 ?603次閱讀

    NIOSII那些事兒REV7.0

    NIOSII那些事兒REV7.0
    發表于 03-07 11:54

    FPGA那些事兒-驅動篇I

    FPGA那些事兒-驅動篇I
    發表于 09-28 13:58

    mos管的那些事兒分享!

    通俗易懂,百度上要下載券,我直接在其他網站下了,在這里發出來,備用。MOS管的那些事兒.rar (1.33 MB )
    發表于 08-28 00:43

    和線程有什么區別

    和線程的區別和線程的共同目的之一是實現系統資源的上下文調用,不過它們的實現層級不同;線程(Thraed)是比進程小一級的的運行單位,多線程實現系統資源上下文調用,是編程語言交付
    發表于 12-10 06:23

    電源選型的那些事兒

    電路教程相關知識的資料,關于電源選型的那些事兒
    發表于 10-10 14:34 ?0次下載

    Linux的那些事兒之我是Sysfs

    Linux的那些事兒之我是Sysfs
    發表于 10-29 09:28 ?5次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是Sysfs

    Linux的那些事兒之我是SCSI硬盤

    Linux的那些事兒之我是SCSI硬盤
    發表于 10-29 09:32 ?19次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是SCSI硬盤

    Linux的那些事兒之我是PCI

    Linux的那些事兒之我是PCI
    發表于 10-29 09:35 ?10次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是PCI

    Linux的那些事兒之我是Hub

    Linux的那些事兒之我是Hub
    發表于 10-29 09:37 ?7次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是Hub

    Linux的那些事兒之我是EHCI主機控制器

    Linux的那些事兒之我是EHCI主機控制器
    發表于 10-29 09:40 ?3次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是EHCI主機控制器

    Linux的那些事兒之我是Block層

    Linux的那些事兒之我是Block層
    發表于 10-29 09:43 ?9次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是Block層

    分析電路:談談反射的那些事兒資料下載

    電子發燒友網為你提供分析電路:談談反射的那些事兒資料下載的電子資料下載,更有其他相關的電路圖、源代碼、課件教程、中文資料、英文資料、參考設計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發表于 04-03 08:48 ?5次下載
    分析電路:<b class='flag-5'>談談</b>反射的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>資料下載

    MOS管的那些事兒.課件下載

    MOS管的那些事兒.課件下載
    發表于 12-06 15:14 ?0次下載

    RFID和NFC之間的那些事兒,你真的了解嗎?

    RFID和NFC之間的那些事兒,你真的了解嗎?
    的頭像 發表于 12-15 09:38 ?666次閱讀
    RFID和NFC之間的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>,你真的了解嗎?
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>