溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#怎么實現(xiàn)CSP并發(fā)模型

發(fā)布時間:2022-04-01 16:04:45 來源:億速云 閱讀:260 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“C#怎么實現(xiàn)CSP并發(fā)模型”,在日常操作中,相信很多人在C#怎么實現(xiàn)CSP并發(fā)模型問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C#怎么實現(xiàn)CSP并發(fā)模型”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    CSP(Communicating sequential processes)

    這東西我一開始以為很簡單,后面差了資料發(fā)現(xiàn)它獨樹一幟,自己是一門語言,也是一套理論。這邊我不深入的對它做過多的見解,我怕耽誤大家=_=,大家可以看看wiki。

    wiki:https://en.wikipedia.org/wiki/Communicating_sequential_processes

    我們從Go的角度對它進行一些分析,摘抄一段概要:

    “用于描述兩個獨立的并發(fā)實體通過共享的通訊 channel(管道)進行通信的并發(fā)模型。 CSP中channel是第一類對象,它不關注發(fā)送消息的實體,而關注與發(fā)送消息時使用的channel?!?/p>

    好了,單獨寫出 CSP 是為了讓大家了解這是一套獨立于語言的東西,大家有興趣可以查看wiki和搜索一些其它資料。

    在Go中的CSP

    Channel(通道)

    Goroutine(不知道怎么翻譯,大家可以理解成一個“工作者”,不是工作者線程。本質是實現(xiàn)了協(xié)程。)

    協(xié)程(提升并發(fā)的利器)

    大家都很明白線程能做什么,但協(xié)程是個什么東西?比起線程又如何呢?

    線程

    我們重新思考一些東西。

    CPU:核心、超線程

    OS:線程

    編程語言:線程池

    這邊不做細講,只是大概點到一下。

    我們所做的任何計算都要經(jīng)由CPU計算,而CPU的核數(shù)直接決定了我們能給CPU執(zhí)行幾件事情。

    我們現(xiàn)在所常用的OS內(nèi)部都有一個輪詢,用時間片的形式來分配任何輪流使用CPU執(zhí)行計算,線程就是這些任務的載體。

    這塊的概念非常龐大(還有牽扯到,什么是并發(fā),什么事并行),本文的重點不是這些,大家有興趣后面可以單獨開一篇文章來解釋這塊的內(nèi)容。

    回歸本文,現(xiàn)在我們知道線程是操作系統(tǒng)級別用來共享CPU的一種技術實現(xiàn),多線程編程早在各大語言遍地開花,被用的惟妙惟肖,百花齊放。

    那么為什么需要協(xié)程呢?

    線程的開銷

    這塊又是一個大知識點,這邊也不多做介紹。

    大家只要明白,線程并不是廉價的,一個線程的創(chuàng)立有至少兩點的開銷

    • 內(nèi)存

    • 調(diào)度器壓力(線程上下文切換等)

    線程是可以持有邏輯數(shù)據(jù)的(比如,HttpContext.Current,等對象)所以必定是占用內(nèi)存的(至于占用了多少內(nèi)存不同的語言和OS不一樣)

    如果一個CPU是4核的,同時就只能處理4件任務,一個OS的線程越多他們輪訓一整圈所耗的時間就更長。而每次調(diào)度線程時都需要復制當前線程上下文的狀態(tài),再去讀取準備調(diào)度線程上下文的狀態(tài)。

    這邊可以看到最后一點,有時候多線程反而會比單線程更加的慢,所以多線程提升性能本質上其實是假的。多線程并不會提升程序性能。

    我知道這邊肯定有人會心存疑問,絕大數(shù)的人都說用多線程來提升性能,為什么這邊說多線程會比單線程慢?

    我們這邊想一下:PHP 和 NodeJS,PHP默認不支持多線程,NodeJS采用單線程事件輪詢,他們的效率比擁有多線程的語言低嗎?并不會。

    多線程之所以快是因為作弊,別人一個人干的事情你叫兩個人去干當然會比單線程快。這也有非常大的限制,多線程所執(zhí)行的東西盡可能避免共享,不然你的效率還是可能不如單線程。

    這邊說的有點跑題,這塊的內(nèi)容實在太大,大家只要知道,線程即使不昂貴也絕不廉價。

    針對這個問題,各大語言都推出了一個叫做線程池的技術,我申請一批線程,持有他,等到有任務的時候直接使用,這樣我就不會頻繁的創(chuàng)建和銷毀線程了。這樣大大提升了效率。

    在.NET中,很早就提倡任何需要線程的時刻都使用 ThreadPool。

    ps:現(xiàn)在覺大多數(shù)(我還沒見過)的語言(runtime)中,線程與操作系統(tǒng)的線程是一一對應的。

    回歸協(xié)程

    協(xié)程與線程是多對一的關系,有多個協(xié)程會對應到一根線程上。跟線程和CPU是一樣的關系。

    線程是為了共享CPU,而協(xié)程是為了共享線程。

    協(xié)程是應用層面的自有“線程”實現(xiàn)。也就是說在不改變OS的線程邏輯下,自己構建了一套 “線程”系統(tǒng)。

    為什么不直接改動OS的線程,讓其更輕?我個人覺得 1是歷史兼容性問題,2是必要性問題,線程是一個很好的抽象邏輯。實現(xiàn)協(xié)程完全可以通過線程來完成。

    協(xié)程的目的

    我們來思考一個場景

    抓取百度、google、bing的html。

    多線程的做法是

    啟動三個線程,分別對百度、google、bing發(fā)起HTTP GET請求。這時候使用了三個線程。

    協(xié)程的做法是(極端)

    啟動一個線程對百度發(fā)起HTTP GET請求,將任務放入隊列,在對google發(fā)起HTTP GET請求,將任務放入隊列,在對bingHTTP GET請求將任務放入隊列。

    這時候只需要使用一個線程(極端情況下,其實大多數(shù)實現(xiàn)來說至少需要兩個線程,因為需要有一個后臺線程去監(jiān)聽任務隊列,當任務完成后再分配一個可用線程去處理下面的邏輯)

    為什么說極端情況下?因為協(xié)程有時候也可能會與線程一一對應,比如你的CPU有8個核心,同時跑4個協(xié)程也有可能會分配4根線程單獨去處理這4個任務,這主要取決于調(diào)度算法。

    總結:協(xié)程是為了提升線程利用率,減少線程的無用功(大多數(shù)是IO堵塞),協(xié)程也更適合IO密集型的場景。

    C#中的協(xié)程

    C#怎么實現(xiàn)CSP并發(fā)模型

    可以看到,3個任務是異步執(zhí)行的,但都由線程4來處理,也就是說三個異步任務只用了一根線程。

    C#中的CSP

    講了這么大篇幅的協(xié)程,終于回歸了今天的主題。

    其實單單實現(xiàn)CSP來說根本不用理清線程和協(xié)程。但今天主要對比的是Go中的CSP,所以如果沒有協(xié)程基本是沒有意義的。

    C#如何對應,CSP中最重要的Channel呢?

    答案就是:BlockingCollection<T>

    我們來看一個例子

    抓取一批網(wǎng)站并輸出網(wǎng)站的title

    發(fā)起 HTTP GET 請求 和分析Title的代碼邏輯如下:

    C#怎么實現(xiàn)CSP并發(fā)模型

    主程序的代碼如下:

    C#怎么實現(xiàn)CSP并發(fā)模型

    執(zhí)行邏輯

    • 啟用一個生產(chǎn)者協(xié)程來根據(jù)url生產(chǎn)對應的html、同時使用主線程消費隊列內(nèi)的內(nèi)容(異步)

    • 每個url單獨起一個協(xié)程來發(fā)起HTTP GET請求

    • 生產(chǎn)者協(xié)程等待所有url的html全部加載完成

    • 標志隊列完成

    • 主線程退出

    執(zhí)行結果如下:

    C#怎么實現(xiàn)CSP并發(fā)模型

    Go協(xié)程與.NET協(xié)程的區(qū)別?

    去除實現(xiàn)上的一些邏輯,本質上沒太多區(qū)別。

    但Go有一個天生優(yōu)勢就是它是新時代的語言,拋棄了線程。也就是說Go層面沒有線程的東西,它只有協(xié)程。

    但.NET中線程已經(jīng)擁有了好多年,大量的類庫、驅動使用線程來完成。

    所以你在上一層就算使用了協(xié)程,執(zhí)行到底部不一定只有一根線程來完成,底部可以自己創(chuàng)建線程來運行邏輯,今天篇幅關系不做過多說明。后面我們在介紹這塊的內(nèi)容。

    到此,關于“C#怎么實現(xiàn)CSP并發(fā)模型”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    csp
    AI