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

示例剖析golang中的CSP并發(fā)模型

 更新時間:2022年05月25日 16:38:16   作者:ThomasYuan  
這篇文章主要為大家介紹了示例剖析golang中的CSP并發(fā)模型,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1. 相關(guān)概念: 

用戶態(tài):當(dāng)一個進(jìn)程在執(zhí)行用戶自己的代碼時處于用戶運(yùn)行態(tài)(用戶態(tài))

內(nèi)核態(tài):當(dāng)一個進(jìn)程因?yàn)橄到y(tǒng)調(diào)用陷入內(nèi)核代碼中執(zhí)行時處于內(nèi)核運(yùn)行態(tài)(內(nèi)核態(tài)),引入內(nèi)核態(tài)防止用戶態(tài)的程序隨意的操作內(nèi)核地址空間,具有一定的安全保護(hù)作用。這種保護(hù)模式是通過內(nèi)存頁表操作等機(jī)制,保證進(jìn)程間的地址空間不會相互沖突,一個進(jìn)程的操作不會修改另一個進(jìn)程地址空間中的數(shù)據(jù)。

用戶態(tài)與內(nèi)核態(tài)之間的切換:當(dāng)在系統(tǒng)中執(zhí)行一個程序時,大部分時間都是運(yùn)行在用戶態(tài)下的,在其需要操作系統(tǒng)幫助完成一些用戶態(tài)自己沒有特權(quán)和能力完成的操作時就會切換到內(nèi)核態(tài)。有以下三種方式:

(1)系統(tǒng)調(diào)用(中斷)用戶態(tài)進(jìn)程主動要求切換到內(nèi)核態(tài)的一種方式。

(2)異常cpu運(yùn)行時如果發(fā)生一些沒有預(yù)知的異常,會觸發(fā)當(dāng)前進(jìn)程切換到處理此異常的內(nèi)核相關(guān)進(jìn)程中?!?/p>

(3)外圍設(shè)備的中斷用戶態(tài)進(jìn)程主動要求切換到內(nèi)核態(tài)的一種方式。

協(xié)程:又稱微線程,纖程。英文名Coroutine。Coroutine是一種運(yùn)行在用戶態(tài)的用戶線程,類似于 greenthread。協(xié)程與線程都相互獨(dú)立,且有自己的上下文,不同之處在于,協(xié)程的切換由其自身控制,而線程的切換收到系統(tǒng)調(diào)度。

2. CSP (通信順序進(jìn)程) 

CSP模型用來描述兩個獨(dú)立的并發(fā)實(shí)體通過共享的通訊channel管道進(jìn)行通信的并發(fā)模型。

golang借用了CSP模型的一些概念如:實(shí)體 process,通道 channel,為之實(shí)現(xiàn)并發(fā)進(jìn)行了理論支持,實(shí)際上并沒有完全實(shí)現(xiàn)CSP模型的所有理論。process是在go語言上的表現(xiàn)就是goroutine,是實(shí)際上并發(fā)執(zhí)行的實(shí)體,每個實(shí)體之間是通過channel通訊來實(shí)現(xiàn)數(shù)據(jù)共享。

3. channel:同步&傳遞消息

channel是被單獨(dú)創(chuàng)建并且可以在進(jìn)程之間傳遞,它的通信模式類似于boss-worker模式,一個實(shí)體通過將消息發(fā)送到channel中,然后又監(jiān)聽這個channel的實(shí)體處理,兩個實(shí)體之間是匿名的,實(shí)現(xiàn)原理上其實(shí)是一個阻塞的消息隊(duì)列。

具體可以分為:有/無緩存channel,只讀channel,只寫channel,雙向channel

寫操作:chan <- value

讀操作:<- chan

// Create channel
// Unbuffered channel
umbuffer_chan := make(chan int)
// Buffered channel
// Buffer Size = 3
buffer_chan := make(chan int,3)
// Read-Only channel
read_channel := make(&lt;-chan int)
// Receive-Only channel
receive_channel := make(chan&lt;- int)

生產(chǎn)者-消費(fèi)者Sample:

package main
import (
   "fmt" 
   "time"
)
// 生產(chǎn)者
func Producer (queue chan&lt;- int){
        for i:= 0; i &lt; 10; i++ {
                queue &lt;- i
        }
}
// 消費(fèi)者
func Consumer( queue &lt;-chan int){
        for i :=0; i &lt; 10; i++{
                v := &lt;- queue
                fmt.Println("receive:", v)
        }
}
func main(){
        queue := make(chan int, 1)
        go Producer(queue)
        go Consumer(queue)
        time.Sleep(1e9) //讓Producer與Consumer完成
}

4. goroutine:實(shí)際并發(fā)執(zhí)行的實(shí)體

在函數(shù)或者方法前面加上關(guān)鍵字go,就創(chuàng)建了并發(fā)運(yùn)行的goroutine,eg:

go func (){
}
func Test(){
}
// ...
go Test()

實(shí)例代碼:

package main  // 代碼包聲明語句。
import (
   "fmt" //系統(tǒng)包用來輸出的
   "math/rand"
   "runtime"
   "sync"
   "time"
)
func main() {
   // 分配一個邏輯處理器給調(diào)度器使用
   runtime.GOMAXPROCS(1)
   // WaitGroup是一個計(jì)數(shù)信號量,用來記錄和維護(hù)運(yùn)行的goroutine,如果當(dāng)前的wg&gt;0,對應(yīng)的exit方法就會阻塞
   var wg sync.WaitGroup
   // 計(jì)數(shù)加2表示要等待兩個goroutine
   wg.Add(2)
   fmt.Printf("Start Goroutines \n", )
   // 聲明匿名函數(shù),創(chuàng)建goroutine
   go func(){
      // 關(guān)鍵字defer會修改函數(shù)調(diào)用時機(jī),在函數(shù)退出時調(diào)用Done來通知main函數(shù)工作已經(jīng)完成
      defer wg.Done()
      for count:=0; count&lt;3; count++ {
         for char :='a'; char&lt;'a'+26 ; char++ {
            fmt.Printf("%c ", char)
         }
      }
   }()
   // 聲明匿名函數(shù),創(chuàng)建goroutine
   go func() {
      // 函數(shù)退出時調(diào)用Done來通知main函數(shù)工作已經(jīng)完成
      defer wg.Done()
      for count:=0; count&lt;3; count++ {
         for char :='A'; char&lt;'A'+26 ; char++ {
            fmt.Printf("%c ", char)
         }
      }
   }()
   fmt.Println("Waiting to finish!\n", )
   // 等待結(jié)束
   wg.Wait()
   fmt.Println("\nTerminate program! \n", )
}

5. golang調(diào)度器

OS在物理處理器上調(diào)度線程來運(yùn)行,而golang在邏輯處理器上調(diào)度goroutine來運(yùn)行。每個邏輯處理器都分別綁定到單個操作系統(tǒng)線程。

如果創(chuàng)建一個goroutine并準(zhǔn)備運(yùn)行,這個goroutine就會被放到調(diào)度器的全局運(yùn)行隊(duì)列中。之后,調(diào)度器就會將隊(duì)列中的goroutine分配給一個邏輯處理器,并放到這個邏輯處理器對應(yīng)的本地運(yùn)行隊(duì)列中。本地運(yùn)行隊(duì)列中的goroutine會一直等待,知道自己被分配到相應(yīng)的邏輯處理器上運(yùn)行。

eg:

其中:

M:Machine,一個M直接關(guān)聯(lián)了一個內(nèi)核線程。

P:Processor,代表了M所需要的上下文環(huán)境,也就是處理用戶級代碼邏輯的處理器。

G:Goroutine,本質(zhì)上是一種輕量級的線程--協(xié)程。

MPG模型,三者關(guān)系的宏觀圖為:

Processor的作用:

當(dāng)內(nèi)核線程阻塞的時候,由于上下文的存在,我們能夠直接放開其他線程,繼續(xù)去執(zhí)行未阻塞的線程,例子如下:

如果當(dāng)前,G0由于I/O,系統(tǒng)調(diào)用進(jìn)行了阻塞,這個時候M0就可以放開其他的線程:

M0和G0進(jìn)行系統(tǒng)調(diào)用,等待返回值,上下文P以及routine隊(duì)列交由M1進(jìn)行執(zhí)行。當(dāng)M0執(zhí)行系統(tǒng)調(diào)用結(jié)束后,M0會嘗試去steal("偷")一個上下文,如果不成功,M0就把它的G0放到一個全局的運(yùn)行隊(duì)列中,然后將自己放到線程池或者轉(zhuǎn)入休眠狀態(tài)。

Global runqueue是各個上下文P在運(yùn)行完自己的本地的goroutine runqueue后用來拉取新的goroutine的地方(steal working算法)。此外,P也會周期性的檢查Global runqueue上的goroutine,來防止全局上的goroutine因?yàn)榈貌坏綀?zhí)行而餓死。

以上就是示例剖析golang中的CSP并發(fā)模型的詳細(xì)內(nèi)容,更多關(guān)于golang CSP并發(fā)模型的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang實(shí)現(xiàn)多存儲驅(qū)動設(shè)計(jì)SDK案例

    Golang實(shí)現(xiàn)多存儲驅(qū)動設(shè)計(jì)SDK案例

    這篇文章主要介紹了Golang實(shí)現(xiàn)多存儲驅(qū)動設(shè)計(jì)SDK案例,Gocache是一個基于Go語言編寫的多存儲驅(qū)動的緩存擴(kuò)展組件,更多具體內(nèi)容感興趣的小伙伴可以參考一下
    2022-09-09
  • golang代碼中調(diào)用Linux命令

    golang代碼中調(diào)用Linux命令

    本文主要介紹了golang代碼中調(diào)用Linux命令,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Golang并發(fā)利器sync.Once的用法詳解

    Golang并發(fā)利器sync.Once的用法詳解

    在某些場景下,我們需要初始化一些資源。有時會采用延遲初始化的方式,在真正需要資源的時候才進(jìn)行初始化。在這種情況下,Go語言中的sync.Once提供一個優(yōu)雅且并發(fā)安全的解決方案,本文將對其進(jìn)行詳細(xì)介紹
    2023-04-04
  • Golang連接并操作PostgreSQL數(shù)據(jù)庫基本操作

    Golang連接并操作PostgreSQL數(shù)據(jù)庫基本操作

    PostgreSQL是常見的免費(fèi)的大型關(guān)系型數(shù)據(jù)庫,具有豐富的數(shù)據(jù)類型,也是軟件項(xiàng)目常用的數(shù)據(jù)庫之一,下面這篇文章主要給大家介紹了關(guān)于Golang連接并操作PostgreSQL數(shù)據(jù)庫基本操作的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • Go實(shí)踐反向代理ReverseProxy解析

    Go實(shí)踐反向代理ReverseProxy解析

    這篇文章主要為大家介紹了Go實(shí)踐反向代理示例ReverseProxy解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 在Go語言中實(shí)現(xiàn)DDD領(lǐng)域驅(qū)動設(shè)計(jì)實(shí)例探究

    在Go語言中實(shí)現(xiàn)DDD領(lǐng)域驅(qū)動設(shè)計(jì)實(shí)例探究

    本文將詳細(xì)探討在Go項(xiàng)目中實(shí)現(xiàn)DDD的核心概念、實(shí)踐方法和實(shí)例代碼,包括定義領(lǐng)域模型、創(chuàng)建倉庫、實(shí)現(xiàn)服務(wù)層和應(yīng)用層,旨在提供一份全面的Go DDD實(shí)施指南
    2024-01-01
  • GO語言數(shù)組和切片實(shí)例詳解

    GO語言數(shù)組和切片實(shí)例詳解

    這篇文章主要介紹了GO語言數(shù)組和切片的用法,以實(shí)例形式較為詳細(xì)的分析了GO語言中數(shù)組與切片的創(chuàng)建及使用技巧,是深入學(xué)習(xí)GO語言的基礎(chǔ),需要的朋友可以參考下
    2014-12-12
  • Go語言interface詳解

    Go語言interface詳解

    這篇文章主要介紹了Go語言interface詳解,本文講解了什么是interface、interface類型、interface值、空interface、interface函數(shù)參數(shù)等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實(shí)例詳解

    Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實(shí)例詳解

    這篇文章主要為大家介紹了Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • golang 格式化輸入輸出操作

    golang 格式化輸入輸出操作

    這篇文章主要介紹了golang 格式化輸入輸出操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論

曲阜市| 灵台县| 梁河县| 叙永县| 黄浦区| 肇庆市| 大邑县| 微博| 青阳县| 同仁县| 峡江县| 长泰县| 多伦县| 邵东县| 施甸县| 凤城市| 株洲市| 宁明县| 武邑县| 喀什市| 隆昌县| 托克托县| 明星| 通江县| 大渡口区| 闸北区| 宣城市| 孟州市| 贡觉县| 郴州市| 年辖:市辖区| 庄浪县| 彭州市| 儋州市| 金川县| 潜江市| 云阳县| 汉源县| 石景山区| 景泰县| 和静县|