當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 程序喵大人
[導(dǎo)讀]前言大家好,我的朋友們!大白干了6年多后端,寫過(guò)C/C、Python、Go,每次說(shuō)到協(xié)程的時(shí)候,腦海里就只能浮現(xiàn)一些關(guān)鍵字yeild、async、go等等。但是對(duì)于協(xié)程這個(gè)知識(shí)點(diǎn),我理解的一直比較模糊,于是決定搞清楚。全文閱讀預(yù)計(jì)耗時(shí)10分鐘,少刷幾個(gè)小視頻的時(shí)間,多學(xué)點(diǎn)知識(shí),想...

前言

大家好,我的朋友們!


大白干了6年多后端,寫過(guò)C/C 、Python、Go,每次說(shuō)到協(xié)程的時(shí)候,腦海里就只能浮現(xiàn)一些關(guān)鍵字yeild、async、go等等。


但是對(duì)于協(xié)程這個(gè)知識(shí)點(diǎn),我理解的一直比較模糊,于是決定搞清楚。


全文閱讀預(yù)計(jì)耗時(shí)10分鐘,少刷幾個(gè)小視頻的時(shí)間,多學(xué)點(diǎn)知識(shí),想想就很劃算噻!


協(xié)程概念的誕生

先拋一個(gè)粗淺的結(jié)論:協(xié)程從廣義來(lái)說(shuō)是一種設(shè)計(jì)理念,我們常說(shuō)的只是具體的實(shí)現(xiàn)。


理解好思想,技術(shù)點(diǎn)就很簡(jiǎn)單了,關(guān)于協(xié)程道與術(shù)的區(qū)別:


上古神器COBOL

協(xié)程概念的出現(xiàn)比線程更早,甚至可以追溯到20世紀(jì)50年代,提協(xié)程就必須要說(shuō)到一門生命力極強(qiáng)的最早的高級(jí)編程語(yǔ)言COBOL。


最開始我以為COBOL這門語(yǔ)言早就消失在歷史長(zhǎng)河中,但是我錯(cuò)了。


COBOL語(yǔ)言,是一種面向過(guò)程的高級(jí)程序設(shè)計(jì)語(yǔ)言,主要用于數(shù)據(jù)處理,是國(guó)際上應(yīng)用最廣泛的一種高級(jí)語(yǔ)言。COBOL是英文Common Business-Oriented Language的縮寫,原意是面向商業(yè)的通用語(yǔ)言。


截止到今年在全球范圍內(nèi)大約有1w臺(tái)大型機(jī)中有3.8w 遺留系統(tǒng)中約2000億行代碼是由COBOL寫的,占比高達(dá)65%,同時(shí)在美國(guó)很多政府和企業(yè)機(jī)構(gòu)都是基于COBOL打造的,影響力巨大。


時(shí)間拉回1958年,美國(guó)計(jì)算機(jī)科學(xué)家梅爾文·康威(Melvin Conway)就開始鉆研基于磁帶存儲(chǔ)的COBOL的編譯器優(yōu)化問(wèn)題,這在當(dāng)時(shí)是個(gè)非常熱門的話題,不少青年才俊都撲進(jìn)去了,包括圖靈獎(jiǎng)得主唐納德·爾文·克努斯教授(Donald Ervin Knuth)也寫了一個(gè)優(yōu)化后的編譯器。


看看這兩位的簡(jiǎn)介,我沉默了:


梅爾文·康威(Melvin Conway)也是一位超級(jí)大佬,著名的康威定律提出者。


唐納德·爾文·克努斯是算法和程序設(shè)計(jì)技術(shù)的先驅(qū)者,1974年的圖靈獎(jiǎng)得主,計(jì)算機(jī)排版系統(tǒng)TeX和字型設(shè)計(jì)系統(tǒng)METAFONT的發(fā)明者,他因這些成就和大量創(chuàng)造性的影響深遠(yuǎn)的著作而譽(yù)滿全球,《計(jì)算機(jī)程序設(shè)計(jì)的藝術(shù)》被《美國(guó)科學(xué)家》雜志列為20世紀(jì)最重要的12本物理科學(xué)類專著之一。


那究竟是什么問(wèn)題讓這群天才們投入這么大的精力呢?快來(lái)看看!


COBOL編譯器的技術(shù)難題

我們都是知道高級(jí)編程語(yǔ)言需要借助編譯器來(lái)生成二進(jìn)制可執(zhí)行文件,編譯器的基本步驟包括:讀取字符流、詞法分析、語(yǔ)法分析、語(yǔ)義分析、代碼生成器、代碼優(yōu)化器等。


這種管道式的流程,上一步的輸出作為下一步的輸入,將中間結(jié)果存儲(chǔ)在內(nèi)存即可,這在現(xiàn)代計(jì)算機(jī)上毫無(wú)壓力,但是受限于軟硬件水平,在幾十年前的COBOL語(yǔ)言卻是很難的。


在1958年的時(shí)候,當(dāng)時(shí)的存儲(chǔ)還不發(fā)達(dá),磁帶作為存儲(chǔ)器是1951年在計(jì)算機(jī)中得到應(yīng)用的,所以那個(gè)時(shí)代的COBOL很依賴于磁帶。


其實(shí),我在網(wǎng)上找了很多資料去看當(dāng)時(shí)的編譯器有什么問(wèn)題,只找到了一條:編譯器無(wú)法做到讀一次磁帶就可以完成整個(gè)編譯過(guò)程,也就是所謂的one-pass編譯器還沒(méi)有產(chǎn)生。


當(dāng)時(shí)的COBOL程序被寫在一個(gè)磁帶上,而磁帶不支持隨機(jī)讀寫,只能順序讀,而當(dāng)時(shí)的內(nèi)存又不可能把整個(gè)磁帶的內(nèi)容都裝進(jìn)去,所以一次讀取沒(méi)編譯完就要再?gòu)念^讀。


于是,我腦補(bǔ)了COBOL編譯器和磁帶之間可能的兩種multi-pass形式的交互情況:


  • 可能情況一
    對(duì)于COBOL的編譯器來(lái)說(shuō),要完成詞法分析、語(yǔ)法分析就要從磁帶上讀取程序的源代碼,在之前的編譯器中詞法分析和語(yǔ)法分析是相互獨(dú)立的,這就意味著:


    • 詞法分析時(shí)需要將磁帶從頭到尾過(guò)一遍
    • 語(yǔ)法分析時(shí)需要將磁帶從頭到尾過(guò)一遍
  • 可能情況二
    聽(tīng)過(guò)磁帶的朋友們一定知道磁帶的兩個(gè)基本操作:倒帶和快進(jìn)。
    在完成編譯器的詞法分析和語(yǔ)法分析兩件事情時(shí),需要磁帶反復(fù)的倒帶和快進(jìn)去尋找兩類分析所需的部分,類似于磁盤的尋道,磁頭需要反復(fù)移動(dòng)橫跳,并且當(dāng)時(shí)的磁帶不一定支持隨機(jī)讀寫。


從一些資料可以看到,COBOL當(dāng)時(shí)編譯器各個(gè)環(huán)節(jié)相互獨(dú)立的,這種軟硬件的綜合限制導(dǎo)致無(wú)法實(shí)現(xiàn)one-pass編譯。


協(xié)同式解決方案

在梅爾文·康威的編譯器設(shè)計(jì)中將詞法分析和語(yǔ)法分析合作運(yùn)行,而不再像其他編譯器那樣相互獨(dú)立,兩個(gè)模塊交織運(yùn)行,編譯器的控制流在詞法分析和語(yǔ)法分析之間來(lái)回切換:


  • 當(dāng)詞法分析模塊基于詞素產(chǎn)生足夠多的詞法單元Token時(shí)就控制流轉(zhuǎn)給語(yǔ)法分析
  • 當(dāng)語(yǔ)法分析模塊處理完所有的詞法單元Token時(shí)將控制流轉(zhuǎn)給詞法分析模塊
  • 詞法分析和語(yǔ)法分析各自維護(hù)自身的運(yùn)行狀態(tài),并且具備主動(dòng)讓出和恢復(fù)的能力
可以看到這個(gè)方案的核心思想在于:


梅爾文·康威構(gòu)建的這種協(xié)同工作機(jī)制,需要參與者讓出(yield)控制流時(shí),記住自身狀態(tài),以便在控制流返回時(shí)能從上次讓出的位置恢復(fù)(resume)執(zhí)行。簡(jiǎn)言之,協(xié)程的全部精神就在于控制流的主動(dòng)讓出和恢復(fù)。


這種協(xié)作式的任務(wù)流和計(jì)算機(jī)中斷非常像,在當(dāng)時(shí)條件的限制下,由梅爾文·康威提出的這種讓出/恢復(fù)模式的協(xié)作程序被認(rèn)為是最早的協(xié)程概念,并且基于這種思想可以打造新的COBOL編譯器。


在1963年,梅爾文·康威也發(fā)表了一篇論文來(lái)說(shuō)明自己的這種思想,雖然半個(gè)多世紀(jì)過(guò)去了,有幸我還是找到了這篇論文:


https://melconway.com/Home/pdf/compiler.pdf


說(shuō)實(shí)話這paper真是有點(diǎn)難,時(shí)間過(guò)于久遠(yuǎn),很難有共鳴,最后我放棄了,要不然我或許能搞明白之前編譯器的具體問(wèn)題了。


懷才不遇的協(xié)程

雖然協(xié)程概念出現(xiàn)的時(shí)間比線程還要早,但是協(xié)程一直都沒(méi)有正是登上舞臺(tái),真是有點(diǎn)懷才不遇的趕腳。


我們上學(xué)的時(shí)候,老師就講過(guò)一些軟件設(shè)計(jì)思想,其中主流語(yǔ)言崇尚自頂向下top-down的編程思想:


對(duì)要完成的任務(wù)進(jìn)行分解,先對(duì)最高層次中的問(wèn)題進(jìn)行定義、設(shè)計(jì)、編程和測(cè)試,而將其中未解決的問(wèn)題作為一個(gè)子任務(wù)放到下一層次中去解決。


這樣逐層、逐個(gè)地進(jìn)行定義、設(shè)計(jì)、編程和測(cè)試,直到所有層次上的問(wèn)題均由實(shí)用程序來(lái)解決,就能設(shè)計(jì)出具有層次結(jié)構(gòu)的程序。


C語(yǔ)言就是典型的top-down思想的代表,在main函數(shù)作為入口,各個(gè)模塊依次形成層次化的調(diào)用關(guān)系,同時(shí)各個(gè)模塊還有下級(jí)的子模塊,同樣有層次調(diào)用關(guān)系。


但是協(xié)程這種相互協(xié)作調(diào)度的思想和top-down是不合的,在協(xié)程中各個(gè)模塊之間存在很大的耦合關(guān)系,并不符合高內(nèi)聚低耦合的編程思想,相比之下top-down使程序結(jié)構(gòu)清晰、層次調(diào)度明確,代碼可讀性和維護(hù)性都很不錯(cuò)。


與線程相比,協(xié)作式任務(wù)系統(tǒng)讓調(diào)用者自己來(lái)決定什么時(shí)候讓出,比操作系統(tǒng)的搶占式調(diào)度所需要的時(shí)間代價(jià)要小很多,后者為了能恢復(fù)現(xiàn)場(chǎng)會(huì)在切換線程時(shí)保存相當(dāng)多的狀態(tài),并且會(huì)非常頻繁地進(jìn)行切換,資源消耗更大。


綜合來(lái)說(shuō),協(xié)程完全是用戶態(tài)的行為,由程序員自己決定什么時(shí)候讓出控制權(quán),保存現(xiàn)場(chǎng)和切換恢復(fù)使用的資源也非常少,同時(shí)對(duì)提高處理器效率來(lái)說(shuō)也是完全符合的。


那么不禁要問(wèn):協(xié)程看著不錯(cuò),為啥沒(méi)成為主流呢?


  • 協(xié)程的思想和當(dāng)時(shí)的主流不符合
  • 搶占式的線程可以解決大部分的問(wèn)題,讓使用者感受的痛點(diǎn)不足
換句話說(shuō):協(xié)程能干的線程干得也不錯(cuò),線程干的不好的地方,使用者暫時(shí)也不太需要,所以協(xié)程就這樣懷才不遇了。


其實(shí),協(xié)程雖然在x86架構(gòu)上沒(méi)有折騰出大風(fēng)浪,由于搶占式任務(wù)系統(tǒng)依賴于CPU硬件的支持,對(duì)硬件要求比較高,對(duì)于一些嵌入式設(shè)備來(lái)說(shuō),協(xié)同調(diào)度再合適不過(guò)了,所以協(xié)程在另外一個(gè)領(lǐng)域也施展了拳腳。


協(xié)程的雄起

我們對(duì)于CPU的壓榨從未停止。


對(duì)于CPU來(lái)說(shuō),任務(wù)分為兩大類:計(jì)算密集型和IO密集型。


計(jì)算密集型已經(jīng)可以最大程度發(fā)揮CPU的作用,但是IO密集型一直是提高CPU利用率的難點(diǎn)。


IO密集型任務(wù)之痛

對(duì)于IO密集型任務(wù),在搶占式調(diào)度中也有對(duì)應(yīng)的解決方案:異步 回調(diào)。


也就是遇到IO阻塞,比如下載圖片時(shí)會(huì)立即返回,等待下載完成將結(jié)果進(jìn)行回調(diào)處理,交付給發(fā)起者。


就像你常去早餐店,油條還沒(méi)好,你和老板很熟悉就先交了錢去座位玩手機(jī)了,等你的油條好了,服務(wù)員就端過(guò)去了,這就是典型的異步 回調(diào)。


雖然異步 回調(diào)在現(xiàn)實(shí)生活中看著也很簡(jiǎn)單,但是在程序設(shè)計(jì)上卻很讓人頭痛,在某些場(chǎng)景下會(huì)讓整個(gè)程序的可讀性非常差,而且也不好寫,相反同步IO雖然效率低,但是很好寫,


還是以為異步圖片下載為例,圖片服務(wù)中臺(tái)提供了異步接口,發(fā)起者請(qǐng)求之后立即返回,圖片服務(wù)此時(shí)給了發(fā)起者一個(gè)唯一標(biāo)識(shí)ID,等圖片服務(wù)完成下載后把結(jié)果放到一個(gè)消息隊(duì)列,此時(shí)需要發(fā)起者不斷消費(fèi)這個(gè)MQ才能拿到下載結(jié)果。


整個(gè)過(guò)程相比同步IO來(lái)說(shuō),原來(lái)整體的邏輯被拆分為好幾個(gè)部分,各個(gè)子部分有狀態(tài)的遷移,對(duì)大部分程序員來(lái)說(shuō)維護(hù)狀態(tài)簡(jiǎn)直就是噩夢(mèng),日后必然是bug的高發(fā)地。


用戶態(tài)協(xié)同調(diào)度

隨著網(wǎng)絡(luò)技術(shù)的發(fā)展和高并發(fā)要求,對(duì)于搶占式調(diào)度對(duì)IO型任務(wù)處理的低效逐漸受到重視,終于協(xié)程的機(jī)會(huì)來(lái)了。


協(xié)程將IO的處理權(quán)交給了程序員,遇到IO被阻塞時(shí)就交出控制權(quán)給其他協(xié)程,等其他協(xié)程處理完再把控制權(quán)交回來(lái)。


通過(guò)yield方式轉(zhuǎn)移執(zhí)行權(quán)的多個(gè)協(xié)程之間并非調(diào)用者和被調(diào)用者的關(guān)系,而是彼此平等、對(duì)稱、合作的關(guān)系。


協(xié)程一直沒(méi)有占上風(fēng)的原因,除了設(shè)計(jì)思想的矛盾,還有一些其他原因,畢竟協(xié)程也不是銀彈,來(lái)看看協(xié)程有什么問(wèn)題:


  • 協(xié)程無(wú)法利用多核,需要配合進(jìn)程來(lái)使用才可以在多CPU上發(fā)揮作用
  • 線程的回調(diào)機(jī)制仍然有巨大生命力,協(xié)程無(wú)法全部替代
  • 控制權(quán)需要轉(zhuǎn)移可能造成某些協(xié)程的饑餓,搶占式更加公平
  • 協(xié)程的控制權(quán)由用戶態(tài)決定可能轉(zhuǎn)移給某些惡意的代碼,搶占式由操作系統(tǒng)來(lái)調(diào)度更加安全
綜上來(lái)說(shuō),協(xié)程和線程并非矛盾,協(xié)程的威力在于IO的處理,恰好這部分是線程的軟肋,由對(duì)立轉(zhuǎn)換為合作才能開辟新局面。


擁抱協(xié)程的編程語(yǔ)言

網(wǎng)絡(luò)操作、文件操作、數(shù)據(jù)庫(kù)操作、消息隊(duì)列操作等重IO操作,是任何高級(jí)編程語(yǔ)言無(wú)法避開的問(wèn)題,也是提高程序效率的關(guān)鍵。


像Java、C/C 、Python這些老牌語(yǔ)言也陸續(xù)開始借助于第三方包來(lái)支持協(xié)程,來(lái)解決自身語(yǔ)言的不足。


像Golang這種新生選手,在語(yǔ)言層面原生支持了協(xié)程,可以說(shuō)是徹底擁抱協(xié)程,這也造就了Go的高并發(fā)能力。


我們來(lái)分別看看它們是怎么實(shí)現(xiàn)協(xié)程的,以及實(shí)現(xiàn)協(xié)程的關(guān)鍵點(diǎn)是什么。


Python

Python對(duì)協(xié)程的支持也經(jīng)歷了多個(gè)版本,從部分支持到完善支持一直在演進(jìn):


  • Python2.x對(duì)協(xié)程的支持比較有限,生成器yield實(shí)現(xiàn)了一部分但不完全
  • 第三方庫(kù)gevent對(duì)協(xié)程的實(shí)現(xiàn)有比較好,但不是官方的
  • Python3.4加入了asyncio模塊
  • 在Python3.5中又提供了async/await語(yǔ)法層面的支持
  • Python3.6中asyncio模塊更加完善和穩(wěn)
  • Python3.7開始async/await成為保留關(guān)鍵字
我們以最新的async/await來(lái)說(shuō)明Python的協(xié)程是如何使用的:


import asyncio
from pathlib import Path
import logging
from urllib.request import urlopen, Request
import os
from time import time
import aiohttp

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


CODEFLEX_IMAGES_URLS = ['https://codeflex.co/wp-content/uploads/2021/01/pandas-dataframe-python-1024x512.png',
'https://codeflex.co/wp-content/uploads/2021/02/github-actions-deployment-to-eks-with-kustomize-1024x536.jpg',
'https://codeflex.co/wp-content/uploads/2021/02/boto3-s3-multipart-upload-1024x536.jpg',
'https://codeflex.co/wp-content/uploads/2018/02/kafka-cluster-architecture.jpg',
'https://codeflex.co/wp-content/uploads/2016/09/redis-cluster-topology.png']


async def download_image_async(session, dir, img_url):
download_path = dir / os.path.basename(img_url)
async with session.get(img_url) as response:
with download_path.open('wb') as f:
while True:
chunk = await response.content.read(512)
if not chunk:
break
f.write(chunk)
logger.info('Downloaded: ' img_url)


async def main():
images_dir = Path("codeflex_images")
Path("codeflex_images").mkdir(parents=False, exist_ok=True)

async with aiohttp.ClientSession() as session:
tasks = [(download_image_async(session, images_dir, img_url)) for img_url in CODEFLEX_IMAGES_URLS]
await asyncio.gather(*tasks, return_exceptions=True)


if __name__ == '__main__':
start = time()

event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main())
finally:
event_loop.close()

logger.info('Download time: %s seconds', time() - start)
這段代碼展示了如何使用async/await來(lái)實(shí)現(xiàn)圖片的并發(fā)下載功能。


  • 在普通的函數(shù)def前面加async關(guān)鍵字就變成異步/協(xié)程函數(shù),調(diào)用該函數(shù)并不會(huì)運(yùn)行,而是返回一個(gè)協(xié)程對(duì)象,后續(xù)在event_loop中執(zhí)行
  • await表示等待task執(zhí)行完成,也就是yeild讓出控制權(quán),同時(shí)asyncio使用事件循環(huán)event_loop來(lái)實(shí)現(xiàn)整個(gè)過(guò)程,await需要在async標(biāo)注的函數(shù)中使用
  • event_loop事件循環(huán)充當(dāng)管理者的角色,將控制權(quán)在幾個(gè)協(xié)程函數(shù)之間切換

C

在C 20引入?yún)f(xié)程框架,但是很不成熟,換句話說(shuō)是給寫協(xié)程庫(kù)的大佬用的最底層的東西,用起來(lái)就很復(fù)雜門檻比較高。


C 作為高性能服務(wù)器開發(fā)語(yǔ)言的無(wú)冕之王,各大公司也做了很多嘗試來(lái)使用協(xié)程功能,比如boost.coroutine、微信的libco、libgo、云風(fēng)用C實(shí)現(xiàn)的協(xié)程庫(kù)等。


說(shuō)實(shí)話,C 協(xié)程相關(guān)的東西有點(diǎn)復(fù)雜,后面專門寫一下,在此不展開了。


Go

go中的協(xié)程被稱為goroutine,被認(rèn)為是用戶態(tài)更輕量級(jí)的線程,協(xié)程對(duì)操作系統(tǒng)而言是透明的,也就是操作系統(tǒng)無(wú)法直接調(diào)度協(xié)程,因此必須有個(gè)中間層來(lái)接管goroutine。


goroutine仍然是基于線程來(lái)實(shí)現(xiàn)的,因?yàn)榫€程才是CPU調(diào)度的基本單位,在go語(yǔ)言內(nèi)部維護(hù)了一組數(shù)據(jù)結(jié)構(gòu)和N個(gè)線程,協(xié)程的代碼被放進(jìn)隊(duì)列中來(lái)由線程來(lái)實(shí)現(xiàn)調(diào)度執(zhí)行,這就是著名的GMP模型。


  • G:Goroutine
每個(gè)Gotoutine對(duì)應(yīng)一個(gè)G結(jié)構(gòu)體,G存儲(chǔ)Goroutine的運(yùn)行堆棧,狀態(tài),以及任務(wù)函數(shù),可重用函數(shù)實(shí)體G需要保存到P的隊(duì)列或者全局隊(duì)列才能被調(diào)度執(zhí)行。


  • M:machine
M是線程的抽象,代表真正執(zhí)行計(jì)算的資源,在綁定有效的P后,進(jìn)入調(diào)度執(zhí)行循環(huán),M會(huì)從P的本地隊(duì)列來(lái)執(zhí)行,


  • P:Processor
P是一個(gè)抽象的概念,不是物理上的CPU而是表示邏輯處理器。當(dāng)一個(gè)P有任務(wù),需要?jiǎng)?chuàng)建或者喚醒一個(gè)系統(tǒng)線程M去處理它隊(duì)列中的任務(wù)。


P決定同時(shí)執(zhí)行的任務(wù)的數(shù)量,GOMAXPROCS限制系統(tǒng)線程執(zhí)行用戶層面的任務(wù)的數(shù)量。


對(duì)M來(lái)說(shuō),P提供了相關(guān)的執(zhí)行環(huán)境,入內(nèi)存分配狀態(tài),任務(wù)隊(duì)列等。


GMP模型運(yùn)行的基本過(guò)程:


  • 首先創(chuàng)建一個(gè)G對(duì)象,然后G被保存在P的本地隊(duì)列或者全局隊(duì)列
  • 這時(shí)P會(huì)喚醒一個(gè)M,M尋找一個(gè)空閑的P將G移動(dòng)到它自己,然后M執(zhí)行一個(gè)調(diào)度循環(huán):調(diào)用G對(duì)象->執(zhí)行->清理線程->繼續(xù)尋找Goroutine。
  • 在M的執(zhí)行過(guò)程中,上下文切換隨時(shí)發(fā)生。當(dāng)切換發(fā)生,任務(wù)的執(zhí)行現(xiàn)場(chǎng)需要被保護(hù),這樣在下一次調(diào)度執(zhí)行可以進(jìn)行現(xiàn)場(chǎng)恢復(fù)。
  • M的棧保存在G對(duì)象,只有現(xiàn)場(chǎng)恢復(fù)需要的寄存器(SP,PC等),需要被保存到G對(duì)象。

總結(jié)

本文通過(guò)1960年對(duì)COBOL語(yǔ)言編譯器的one-pass問(wèn)題的介紹,讓大家看到了協(xié)同式程序的最早背景以及主動(dòng)讓出/恢復(fù)的重要理念。


緊接著介紹了主流的自頂向下的軟件設(shè)計(jì)思想和協(xié)程思想的矛盾所在,并且搶占式程序調(diào)度的蓬勃發(fā)展,以及存在的問(wèn)題。


繼續(xù)介紹了關(guān)于IO密集型任務(wù)對(duì)于提升CPU效率的阻礙,搶占式調(diào)度對(duì)于IO密集型問(wèn)題的異步 回調(diào)的解決方案,以及協(xié)程的處理,展示了協(xié)程在IO密集型任務(wù)上處理的重大優(yōu)勢(shì)。


最后說(shuō)明了當(dāng)前搶占式調(diào)度 協(xié)程IO密集型處理的方案,包括Python、C 和go的語(yǔ)言層面對(duì)于協(xié)程的支持和實(shí)現(xiàn)。


本文特別具體的內(nèi)容并不多,旨在介紹協(xié)程思想及其優(yōu)勢(shì)所在,對(duì)于各個(gè)語(yǔ)言的協(xié)程實(shí)現(xiàn)細(xì)節(jié)并未展開。








本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉