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

Go語言中并發(fā)的工作原理

 更新時間:2022年07月16日 08:47:49   作者:奮斗的大橙子  
本文詳細講解了Go語言中并發(fā)的工作原理,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、Go語言中Goroutine的基本原理

Go語言里的并發(fā)指的是能讓某個函數(shù)獨立于其他函數(shù)運行的能力。

Go語言的goroutine是一個獨立的工作單元,

Go 語言的并發(fā)同步模型來自一個叫作通信順序進程(Communicating Sequential Processes,CSP)的范型(paradigm)。

CSP 是一種消息傳遞模型,通過在goroutine 之間傳遞數(shù)據(jù)來傳遞消息,而不是對數(shù)據(jù)進行加鎖來實現(xiàn)同步訪問。消息的傳遞通過Go語言中的Channel(通道)來實現(xiàn)。

進程(process) 看作一個包含了應(yīng)用程序在運行中需要用到和維護的各種資源的容器。

線程(Thread)是一個執(zhí)行空間,這個空間會被操作系統(tǒng)調(diào)度來運行函數(shù)中所寫的代碼。

每個進程至少包含一個線程,每個進程的初始線程被稱作主線程。因為執(zhí)行這個線程的空間是應(yīng)用程序的本身的空間,所以當主線程終止時,應(yīng)用程序也會終止。

下圖就是進程和線程的簡要關(guān)系。

補充:句柄是什么?

我的理解句柄就是給用戶操作內(nèi)核資源的指針,指向指針的指針。【把手】和【門】的關(guān)系,使用們把手能轉(zhuǎn)動整個門(系統(tǒng)資源)

操作系統(tǒng)會在物理處理器上調(diào)度線程來運行,而Go 語言的運行時會在邏輯處理器上調(diào)度goroutine來運行。每個邏輯處理器都分別綁定到單個操作系統(tǒng)線程。下面我們就來簡單描述一下goroutine執(zhí)行的流程。

首先來了解一下操作系統(tǒng)線程、邏輯處理器和本地運行隊列

全局運行隊列:剛創(chuàng)建的goruntine會被安排到這里面,通過一些調(diào)度算法,分配給邏輯處理器

操作系統(tǒng)線程:這個就是傳統(tǒng)意義上的線程,用于具體goroutine的執(zhí)行,他會和一個邏輯器進行綁定

邏輯處理器:里面維護著一個本地的隊列,用于本地隊列里面goroutine的調(diào)度

本地運行隊列:裝載著待執(zhí)行的goruntine

支撐整個調(diào)度器的主要有4個重要結(jié)構(gòu),分別是M、G、P、Sched,前三個定義在runtime.h中,Sched定義在proc.c中。

  • Sched結(jié)構(gòu)就是調(diào)度器,它維護有存儲M和G的隊列以及調(diào)度器的一些狀態(tài)信息等。
  • M代表內(nèi)核級線程,一個M就是一個線程,goroutine就是跑在M之上的;M是一個很大的結(jié)構(gòu),里面維護小對象內(nèi)存cache(mcache)、當前執(zhí)行的goroutine、隨機數(shù)發(fā)生器等等非常多的信息。
  • P全稱是Processor,處理器,它的主要用途就是用來執(zhí)行g(shù)oroutine的,所以它也維護了一個goroutine隊列,里面存儲了所有需要它來執(zhí)行的goroutine,這個P的角色可能有一點讓人迷惑,一開始容易和M沖突,后面重點聊一下它們的關(guān)系。
  • G就是goroutine實現(xiàn)的核心結(jié)構(gòu)了,G維護了goroutine需要的棧、程序計數(shù)器以及它所在的M等信息。

整個過程描述:

當創(chuàng)建一個Goroutine的時候,先放到全局隊列當中,然后會把這個Goroutine分配到一個邏輯處理器的本地隊列中,這個邏輯處理器會綁定一個操作系統(tǒng)線程,由這個線程去執(zhí)行Goroutine的代碼。

生動描述:

地鼠(gopher)用小車運著一堆待加工的磚。M就可以看作圖中的地鼠,P就是小車,G就是小車里裝的磚。一圖勝千言啊,弄清楚了它們?nèi)叩年P(guān)系,下面我們就開始重點聊地鼠是如何在搬運磚塊的。

1.runqget, 地鼠(M)試圖從自己的小車(P)取出一塊磚(G),當然結(jié)果可能失敗,也就是這個地鼠的小車已經(jīng)空了,沒有磚了。

2.findrunnable, 如果地鼠自己的小車中沒有磚,那也不能閑著不干活是吧,所以地鼠就會試圖跑去工場倉庫取一塊磚來處理;工場倉庫也可能沒磚啊,出現(xiàn)這種情況的時候,這個地鼠也沒有偷懶停下干活,而是悄悄跑出去,隨機盯上一個小伙伴(地鼠),然后從它的車里試圖偷一半磚到自己車里。如果多次嘗試偷磚都失敗了,那說明實在沒有磚可搬了,這個時候地鼠就會把小車還回停車場,然后睡覺休息了。如果地鼠睡覺了,下面的過程當然都停止了,地鼠睡覺也就是線程sleep了。

3.wakep, 到這個過程的時候,可憐的地鼠發(fā)現(xiàn)自己小車里有好多磚啊,自己根本處理不過來;再回頭一看停車場居然有閑置的小車,立馬跑到宿舍一看,你妹,居然還有小伙伴在睡覺,直接給屁股一腳,“你妹,居然還在睡覺,老子都快累死了,趕緊起來干活,分擔(dān)點工作。”,小伙伴醒了,拿上自己的小車,乖乖干活去了。有時候,可憐的地鼠跑到宿舍卻發(fā)現(xiàn)沒有在睡覺的小伙伴,于是會很失望,最后只好向工場老板說——”停車場還有閑置的車啊,我快干不動了,趕緊從別的工場借個地鼠來幫忙吧。”,最后工場老板就搞來一個新的地鼠干活了。

4.execute,地鼠拿著磚放入火種歡快的燒練起來。

注: “地鼠偷磚”叫work stealing,一種調(diào)度算法。

到這里,貌似整個工場都正常的運轉(zhuǎn)起來了,無懈可擊的樣子。不對,還有一個疑點沒解決啊,假設(shè)地鼠的車里有很多磚,它把一塊磚放入火爐中后,何時把它取出來,放入第二塊磚呢?難道要一直把第一塊磚燒練好,才取出來嗎?那估計后面的磚真的是等得花兒都要謝了。這里就是要真正解決goroutine的調(diào)度,上下文切換問題。

goroutine的阻塞

當一個OS線程M0陷入阻塞時(如下圖),P轉(zhuǎn)而在運行M1,圖中的M1可能是正被創(chuàng)建,或者從線程緩存中取出。

簡單解釋就是,當當前的Goroutine在阻塞,就把他和當前線程綁定,讓當前的線程繼續(xù)執(zhí)行這個Goroutine(就是等待),其他的goroutine隨著邏輯處理器被綁定到另一個線程上,繼續(xù)執(zhí)行。

當阻塞的線程返回時,它必須嘗試取得一個邏輯處理器來運行g(shù)oroutine,一般情況下,它會從其他的OS線程那里拿一個P過來,如果沒有拿到的話,它就把goroutine放在一個全局運行隊列里,然后自己睡眠(放入線程緩存里)。所有的P也會周期性的檢查global runqueue并運行其中的goroutine,否則global runqueue上的goroutine永遠無法執(zhí)行。

還有就像下面的圖片,左邊的線程一個滿載狀態(tài),一個沒有g(shù)oroutine,此時的做法就是會進行重新分配,就想右側(cè)圖展示

參考 :https://morsmachine.dk/go-scheduler

二、Go語言中的并發(fā)和并行

并發(fā)是兩個任務(wù)可以在重疊的時間段內(nèi)啟動,運行和完成。并行是任務(wù)在同一時間運行,例如,在多核處理器上。

并發(fā)是獨立執(zhí)行過程的組合,而并行是同時執(zhí)行(可能相關(guān)的)計算。

并發(fā)是一次處理很多事情,并行是同時做很多事情。

  • 應(yīng)用程序可以是并發(fā)的,但不是并行的,這意味著它可以同時處理多個任務(wù),但是沒有兩個任務(wù)在同一時刻執(zhí)行。
  • 應(yīng)用程序可以是并行的,但不是并發(fā)的,這意味著它同時處理多核CPU中的任務(wù)的多個子任務(wù)。
  • 應(yīng)用程序可以即不是并行的,也不是并發(fā)的,這意味著它一次一個地處理所有任務(wù)。
  • 應(yīng)用程序可以即是并行的也是并發(fā)的,這意味著它同時在多核CPU中同時處理多個任務(wù)。

簡單講:并行就是同時做很多事 并發(fā)就是一堆事情一個時間點來了,然后通過分片等方式感覺像都在執(zhí)行

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • Go語言中的range用法實例分析

    Go語言中的range用法實例分析

    這篇文章主要介紹了Go語言中的range用法,實例分析了range的功能與使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • GO的range具體使用

    GO的range具體使用

    GO語言的for…range 能做什么呢?golang的for…range是go 身的語法,可以用來遍歷數(shù)據(jù)結(jié)構(gòu),本文就詳細的來介紹一下具體使用,感興趣的可以了解一下
    2021-10-10
  • 詳解Go strconv包

    詳解Go strconv包

    Go語言中strconv包實現(xiàn)了基本數(shù)據(jù)類型和其字符串表示的相互轉(zhuǎn)換。這篇文章主要介紹了Go strconv包的相關(guān)知識,需要的朋友可以參考下
    2020-10-10
  • Go語言reflect.TypeOf()和reflect.Type通過反射獲取類型信息

    Go語言reflect.TypeOf()和reflect.Type通過反射獲取類型信息

    這篇文章主要介紹了Go語言reflect.TypeOf()和reflect.Type通過反射獲取類型信息,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 1行Go代碼實現(xiàn)反向代理的示例

    1行Go代碼實現(xiàn)反向代理的示例

    這篇文章主要介紹了1行Go代碼實現(xiàn)反向代理的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 基于Golang實現(xiàn)統(tǒng)一加載資源的入口

    基于Golang實現(xiàn)統(tǒng)一加載資源的入口

    當我們需要在?main?函數(shù)中做一些初始化的工作,比如初始化日志,初始化配置文件,都需要統(tǒng)一初始化入口函數(shù),所以本文就來編寫一個統(tǒng)一加載資源的入口吧
    2023-05-05
  • Go語言操作redis用法實例

    Go語言操作redis用法實例

    這篇文章主要介紹了Go語言操作redis用法,實例分析了Go語言操作redis的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Go語言單鏈表實現(xiàn)方法

    Go語言單鏈表實現(xiàn)方法

    這篇文章主要介紹了Go語言單鏈表實現(xiàn)方法,實例分析了基于Go語言的單鏈表實現(xiàn)原理與使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • Go習(xí)慣用法(多值賦值短變量聲明賦值簡寫模式)基礎(chǔ)實例

    Go習(xí)慣用法(多值賦值短變量聲明賦值簡寫模式)基礎(chǔ)實例

    本文為大家介紹了Go習(xí)慣用法(多值賦值,短變量聲明和賦值,簡寫模式、多值返回函數(shù)、comma,ok 表達式、傳值規(guī)則)的基礎(chǔ)實例,幫大家鞏固扎實Go語言基礎(chǔ)
    2024-01-01
  • Golang如何交叉編譯各個平臺的二進制文件詳解

    Golang如何交叉編譯各個平臺的二進制文件詳解

    這篇文章主要給大家介紹了關(guān)于Golang如何交叉編譯各個平臺的二進制文件的相關(guān)資料,并介紹了golang如何讓編譯生產(chǎn)的二進制文件變小,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08

最新評論

涟水县| 乌拉特前旗| 麟游县| 彰武县| 满城县| 涪陵区| 滦平县| 平原县| 甘孜县| 嘉义市| 永清县| 高唐县| 东安县| 千阳县| 东乌| 驻马店市| 二连浩特市| 错那县| 奈曼旗| 商都县| 张家川| 嘉定区| 阜平县| 东丽区| 阿拉善右旗| 呼和浩特市| 邵阳县| 修水县| 长治县| 九龙城区| 锡林浩特市| 庆城县| 会理县| 博爱县| 永泰县| 平顶山市| 金湖县| 吴堡县| 信阳市| 丰都县| 诸城市|