最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#代替go采用的CSP并發(fā)模型實現

 更新時間:2022年04月01日 14:20:48   作者:Ants  
這篇文章主要為大家介紹了C#代替go采用的CSP并發(fā)模型的輕松實現,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪

說起Golang(后面統稱為Go),就想到他的高并發(fā)特性,在深入一些就是 Goroutine。在大家被它優(yōu)雅的語法和簡潔的代碼實現的高并發(fā)程序所折服時,其實C#/.NET也可以很容易的做到。今天我們來參照Go,來用C#實現它所采用的的CSP并發(fā)模型。

CSP(Communicating sequential processes)

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

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

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

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

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

在Go中的CSP

Channel(通道)

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

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

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

線程

我們重新思考一些東西。

CPU:核心、超線程

OS:線程

編程語言:線程池

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

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

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

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

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

那么為什么需要協程呢?

線程的開銷

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

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

  • 內存
  • 調度器壓力(線程上下文切換等)

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

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

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

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

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

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

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

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

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

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

回歸協程

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

線程是為了共享CPU,而協程是為了共享線程。

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

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

協程的目的

我們來思考一個場景

抓取百度、google、bing的html。

多線程的做法是

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

協程的做法是(極端)

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

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

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

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

C#中的協程

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

C#中的CSP

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

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

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

答案就是:BlockingCollection<T>

我們來看一個例子

抓取一批網站并輸出網站的title

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

主程序的代碼如下:

執(zhí)行邏輯

  • 啟用一個生產者協程來根據url生產對應的html、同時使用主線程消費隊列內的內容(異步)
  • 每個url單獨起一個協程來發(fā)起HTTP GET請求
  • 生產者協程等待所有url的html全部加載完成
  • 標志隊列完成
  • 主線程退出

執(zhí)行結果如下:

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

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

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

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

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

寫在最后

最后總結一個要點,多線程、協程并不能提升性能,它們所達到的目的只是提高CPU利用率。

今天本來想詳細寫B(tài)lockingCollection<T>的使用說明,但協程等概念占了大量的篇幅,后面我們再來詳細介紹.NET中的異步編程。

以上就是C#代替go采用的CSP并發(fā)模型實現的詳細內容,更多關于C#實現go采用CSP并發(fā)模型的資料請關注腳本之家其它相關文章!

相關文章

  • C# 獲取當前總毫秒數的實例講解

    C# 獲取當前總毫秒數的實例講解

    這篇文章主要介紹了C# 獲取當前總毫秒數的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C#實現QQ聊天窗口

    C#實現QQ聊天窗口

    這篇文章主要為大家詳細介紹了C#實現QQ聊天窗口,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C# DateTime日期比較方法案例詳解

    C# DateTime日期比較方法案例詳解

    這篇文章主要介紹了C# DateTime日期比較方法案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • C#檢測是否有危險字符的SQL字符串過濾方法

    C#檢測是否有危險字符的SQL字符串過濾方法

    這篇文章主要介紹了C#檢測是否有危險字符的SQL字符串過濾方法,功能非常實用,對于程序設計的安全來說至關重要!需要的朋友可以參考下
    2014-07-07
  • 使用C#與設備接口進行無縫通信的實現技巧

    使用C#與設備接口進行無縫通信的實現技巧

    隨著物聯網、智能設備和自動化技術的快速發(fā)展,越來越多的設備需要與計算機系統進行實時通信,而C#作為一門強大的編程語言,憑借其廣泛的庫支持和高效的開發(fā)效率,已成為與設備接口對接的理想選擇,在本篇文章中,我們將探討如何使用C#與設備進行無縫通信
    2025-01-01
  • C#文件加密方法匯總

    C#文件加密方法匯總

    這篇文章主要介紹了C#文件加密方法,實例匯總了常見的加密方法如AES加密類、文件加密類、文件夾加密類等,最后給出完整的實例源碼下載供大家參考借鑒,需要的朋友可以參考下
    2014-11-11
  • c#實現網站監(jiān)控查看是否正常示例

    c#實現網站監(jiān)控查看是否正常示例

    這篇文章主要介紹了使用c#監(jiān)控網站是否正常的功能示例,大家參考使用吧
    2014-01-01
  • WPF開發(fā)之UniformGrid和ItemsControl的應用詳解

    WPF開發(fā)之UniformGrid和ItemsControl的應用詳解

    為了簡化開發(fā),WPF提供了UniformGrid布局和ItemsControl容器,本文以一個簡單的小例子,簡述如何在WPF開發(fā)中應用UniformGrid和ItemsControl實現均勻的布局,希望對大家有所幫助
    2024-01-01
  • C#關機小程序源碼

    C#關機小程序源碼

    這是用所學習的C#做的一個關機小程序,功能不多,只是為了練手,需要的朋友可以參考下
    2012-10-10
  • C#簡單實現表達式目錄樹(Expression)

    C#簡單實現表達式目錄樹(Expression)

    表達式目錄樹以數據形式表示語言級別代碼。數據存儲在樹形結構中。表達式目錄樹中的每個節(jié)點都表示一個表達式。這篇文章給大家介紹C#簡單實現表達式目錄樹(Expression),需要的朋友參考下吧
    2017-11-11

最新評論

丁青县| 南部县| 兴和县| 仁怀市| 定西市| 新乐市| 正阳县| 米脂县| 南江县| 固镇县| 塔城市| 鹤峰县| 依兰县| 于田县| 敦化市| 柘城县| 陆河县| 营山县| 磐石市| 宁夏| 诏安县| 巴楚县| 红河县| 贺州市| 汕头市| 历史| 通山县| 高邮市| 凭祥市| 榆社县| 固镇县| 个旧市| 湾仔区| 岱山县| 禹州市| 乡城县| 枣强县| 南汇区| 金乡县| 高州市| 沙坪坝区|