欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go保證并發(fā)安全底層實(shí)現(xiàn)詳解

 更新時(shí)間:2022年09月02日 09:16:32   作者:Sundar84034  
這篇文章主要為大家介紹了Go保證并發(fā)安全底層實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

上一部分主要寫了鎖,本篇主要介紹Channel

channel是Go中非常重要的一個(gè)數(shù)據(jù)類型,它和goroutine緊密相連,是Go的CSP并發(fā)模型的重要體現(xiàn)。

CSP

  • CSP 是通信順序進(jìn)程(Communicating Sequential Process)的簡稱,是一種并發(fā)編程模型。
  • 簡單來說,CSP模型由并發(fā)的實(shí)體所組成,實(shí)體之間通過發(fā)送消息進(jìn)行通信,而發(fā)送消息使用的就是通道,即channel。
  • GO實(shí)現(xiàn)了CSP部分理論,goroutine對應(yīng)CSP中的并發(fā)執(zhí)行的實(shí)體,channel對應(yīng)CSP中的channel。

不要通過共享內(nèi)存來通信,而應(yīng)該通過通信來共享內(nèi)存

Channel的基本使用

package main
import "fmt"
func main() {
	c := make(chan int)
	go func() {
		c <- 1 // 向channel發(fā)送數(shù)據(jù)
	}()
	x := <-c // 從channel中接收數(shù)據(jù)
	fmt.Println(x)
}

1、通過make(chan int)創(chuàng)建一個(gè)int channel(可以在channel初始化時(shí)指定緩沖區(qū)的大小,例如make(chan int,2),不指定則默認(rèn)為0)

2、在一個(gè)goroutine中,通過c<-1將數(shù)據(jù)發(fā)送到channel中,<-可以理解為數(shù)據(jù)的流動(dòng)方向。

3、在主goroutine中通過x := <-c接收channel中的數(shù)據(jù),并賦值給x。

channel如何保證并發(fā)安全

既然goroutin和channel分別對應(yīng)csp中的實(shí)體和媒介,goroutin之間都是通過chennel來傳遞數(shù)據(jù),那么是如何保證并發(fā)安全的呢?

通過閱讀源碼可以發(fā)現(xiàn),channel內(nèi)部是使用Mutext互斥鎖來保證的( 之前也有人提出CAS無鎖Channel的實(shí)現(xiàn),但因?yàn)闊o鎖Channel在多核測試中的表現(xiàn)和沒有滿足FIFO的特性等原因,該提案目前是擱淺狀態(tài))關(guān)于無鎖channel的討論

channel的底層實(shí)現(xiàn)

channel的核心源碼位于runtime包的chan.go中。

hchan 是 channel 在 golang 中的內(nèi)部實(shí)現(xiàn)

type hchan struct { 
    qcount uint // total data in the queue 
    dataqsiz uint // size of the circular queue 
    buf unsafe.Pointer // points to an array of dataqsiz elements 
    elemsize uint16 
    closed uint32 
    elemtype *_type // element type 
    sendx uint // send index 
    recvx uint // receive index 
    recvq waitq // list of recv waiters 
    sendq waitq // list of send waiters 
    // lock protects all fields in hchan, as well as several 
    // fields in sudogs blocked on this channel. 
    // 
    // Do not change another G's status while holding this lock 
    // (in particular, do not ready a G), as this can deadlock 
    // with stack shrinking. 
    lock mutex 
 } 

hchan的所有屬性大體可以分為3類

1、buffer相關(guān)屬性,當(dāng)channel中的緩沖區(qū)大小不為0時(shí),buffer中存放了待接收的數(shù)據(jù)。

2、waitq相關(guān)屬性,即recvq和sendq,可以理解為一個(gè)標(biāo)準(zhǔn)的FIFO隊(duì)列,recvq是等待接收數(shù)據(jù)的goroutine,sendq是等待發(fā)送數(shù)據(jù)的goroutine。

3、其它,例如lock(互斥鎖)、elemtype(元素類型)、closed(channel 是否關(guān)閉,== 0 代表未 closed)

hchan的所有行為,基本都是圍繞bufferwaitq來實(shí)現(xiàn)的

waitq

type waitq struct { 
 first *sudog 
 last *sudog 
 } 

waitq是一個(gè)雙向鏈表,里面保存了goroutine。

buffe

buffer使用 ring buffer(環(huán)形緩沖區(qū))實(shí)現(xiàn)

在hchan中,可以看到 recvxsendx 兩個(gè)屬性,recvx即當(dāng)前已發(fā)送的元素在隊(duì)列當(dāng)中的索引位置,sendx 即 當(dāng)前已接收的元素在隊(duì)列當(dāng)中的索引位置。

從 recvx 到 sendx 之間的元素,表示已正常存放入 buffer 中的數(shù)據(jù)。

Lock

hchan中的lock就是一個(gè)互斥鎖,channel在發(fā)送和接收數(shù)據(jù)前,都會先進(jìn)行加鎖,待邏輯完成后執(zhí)行再解鎖,來保證并發(fā)安全。

以上就是Go保證并發(fā)安全底層實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于Go并發(fā)安全底層實(shí)現(xiàn)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • golang實(shí)現(xiàn)webgis后端開發(fā)的步驟詳解

    golang實(shí)現(xiàn)webgis后端開發(fā)的步驟詳解

    這篇文章主要介紹如何用golang結(jié)合postgis數(shù)據(jù)庫,使用gin、grom框架實(shí)現(xiàn)后端的MVC的接口搭建,文中有詳細(xì)的流程步驟及代碼示例,需要的朋友可以參考下
    2023-06-06
  • Go?語言sort?中的sortInts?方法

    Go?語言sort?中的sortInts?方法

    這篇文章主要介紹了Go?語言sort?中的sortInts?方法,Go?的?sort?包實(shí)現(xiàn)了內(nèi)置和用戶定義類型的排序。我們將首先查看內(nèi)置函數(shù)的排序,西瓦嗯更多相關(guān)資料需要的小伙伴可以參考一下
    2022-04-04
  • Go語言中的通道channel詳情

    Go語言中的通道channel詳情

    這篇文章主要介紹了Go語言中的通道channel,在Go語言中管道類似于一個(gè)數(shù)據(jù)流,每次放入或者取出一部分?jǐn)?shù)據(jù),數(shù)據(jù)取出后原通道內(nèi)的數(shù)據(jù)就刪除掉,在linux操作系統(tǒng)中管道會將函數(shù)的返回結(jié)果作為下一個(gè)函數(shù)的參數(shù),下文詳細(xì)內(nèi)容需要的朋友可以參考下
    2022-02-02
  • 一文詳解Go語言中Mutex互斥鎖

    一文詳解Go語言中Mutex互斥鎖

    Golang中的Mutex互斥鎖是一種常用的并發(fā)控制機(jī)制,用于保護(hù)共享資源的訪問,在本文中,我們將深入探討Mutex互斥鎖的原理、日常使用、鎖結(jié)構(gòu)以及運(yùn)行機(jī)制,需要的朋友可以參考下
    2023-12-12
  • Go語言中函數(shù)可變參數(shù)(Variadic Parameter)詳解

    Go語言中函數(shù)可變參數(shù)(Variadic Parameter)詳解

    在Python中,在函數(shù)參數(shù)不確定數(shù)量的情況下,可以動(dòng)態(tài)在函數(shù)內(nèi)獲取參數(shù)。在Go語言中,也有類似的實(shí)現(xiàn)方式,本文就來為大家詳細(xì)講解一下
    2022-07-07
  • 一文理解Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn)

    一文理解Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn)

    本文主要介紹了Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Golang簡單實(shí)現(xiàn)http的server端和client端

    Golang簡單實(shí)現(xiàn)http的server端和client端

    Http 服務(wù)是基于 Tcp 的應(yīng)用層的實(shí)現(xiàn),也是最常見的網(wǎng)絡(luò)協(xié)議之一。本文主要介紹了Golang簡單實(shí)現(xiàn)http的server端和client端,感興趣的可以了解一下
    2021-06-06
  • 最新評論