99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

go語言cas go語言cap函數(shù)

Go語言——sync.Map詳解

sync.Map是1.9才推薦的并發(fā)安全的map,除了互斥量以外,還運(yùn)用了原子操作,所以在這之前,有必要了解下 Go語言——原子操作

成都創(chuàng)新互聯(lián)公司長期為近千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為鞏留企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作,鞏留網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

go1.10\src\sync\map.go

entry分為三種情況:

從read中讀取key,如果key存在就tryStore。

注意這里開始需要加鎖,因?yàn)樾枰僮鱠irty。

條目在read中,首先取消標(biāo)記,然后將條目保存到dirty里。(因?yàn)闃?biāo)記的數(shù)據(jù)不在dirty里)

最后原子保存value到條目里面,這里注意read和dirty都有條目。

總結(jié)一下Store:

這里可以看到dirty保存了數(shù)據(jù)的修改,除非可以直接原子更新read,繼續(xù)保持read clean。

有了之前的經(jīng)驗(yàn),可以猜測下load流程:

與猜測的 區(qū)別 :

由于數(shù)據(jù)保存兩份,所以刪除考慮:

先看第二種情況。加鎖直接刪除dirty數(shù)據(jù)。思考下貌似沒什么問題,本身就是臟數(shù)據(jù)。

第一種和第三種情況唯一的區(qū)別就是條目是否被標(biāo)記。標(biāo)記代表刪除,所以直接返回。否則CAS操作置為nil。這里總感覺少點(diǎn)什么,因?yàn)闂l目其實(shí)還是存在的,雖然指針nil。

看了一圈貌似沒找到標(biāo)記的邏輯,因?yàn)閯h除只是將他變成nil。

之前以為這個(gè)邏輯就是簡單的將為標(biāo)記的條目拷貝給dirty,現(xiàn)在看來大有文章。

p == nil,說明條目已經(jīng)被delete了,CAS將他置為標(biāo)記刪除。然后這個(gè)條目就不會(huì)保存在dirty里面。

這里其實(shí)就跟miss邏輯串起來了,因?yàn)閙iss達(dá)到閾值之后,dirty會(huì)全量變成read,也就是說標(biāo)記刪除在這一步最終刪除。這個(gè)還是很巧妙的。

真正的刪除邏輯:

很繞。。。。

Go并發(fā)編程之美-CAS操作

摘要: 一、前言 go語言類似Java JUC包也提供了一些列用于多線程之間進(jìn)行同步的措施,比如低級的同步措施有 鎖、CAS、原子變量操作類。相比Java來說go提供了獨(dú)特的基于通道的同步措施。本節(jié)我們先來看看go中CAS操作 二、CAS操作 go中的Cas操作與java中類似,都是借用了CPU提供的原子性指令來實(shí)現(xiàn)。

go語言類似Java JUC包也提供了一些列用于多線程之間進(jìn)行同步的措施,比如低級的同步措施有 鎖、CAS、原子變量操作類。相比Java來說go提供了獨(dú)特的基于通道的同步措施。本節(jié)我們先來看看go中CAS操作

go中的Cas操作與java中類似,都是借用了CPU提供的原子性指令來實(shí)現(xiàn)。CAS操作修改共享變量時(shí)候不需要對共享變量加鎖,而是通過類似樂觀鎖的方式進(jìn)行檢查,本質(zhì)還是不斷的占用CPU 資源換取加鎖帶來的開銷(比如上下文切換開銷)。下面一個(gè)例子使用CAS來實(shí)現(xiàn)計(jì)數(shù)器

go中CAS操作具有原子性,在解決多線程操作共享變量安全上可以有效的減少使用鎖所帶來的開銷,但是這是使用cpu資源做交換的。

我簡單列舉了并發(fā)編程的大綱,需要詳細(xì)的私信“555”~~

有沒有實(shí)現(xiàn)過cas的golang客戶端

首先理解是錯(cuò)的,不管用戶態(tài)的API(syscall)是否是同步還是異步,在kernel層面都是異步的。其實(shí)實(shí)現(xiàn)原理很簡單,就是利用C(嵌入?yún)R編)語言可以直接修改寄存器(setcontext/setjmp/longjmp均是類似原理,修改程序指針eip實(shí)現(xiàn)跳轉(zhuǎn),棧指針實(shí)現(xiàn)上線文切換)來實(shí)現(xiàn)從func_a調(diào)進(jìn)去,從func_b返回出來這種行為。對于golang來說,func_a/func_b屬于不同的goroutine,從而就實(shí)現(xiàn)了goroutine的調(diào)度切換。另外對于所有可能阻塞的syscall,golang對其進(jìn)行了封裝,底層實(shí)際是epoll方式做的,注冊回調(diào)后切換到另一個(gè)runnable的goroutine。

圖解Go中select語句的底層原理

Go 的select語句是一種僅能用于channl發(fā)送和接收消息的專用語句,此語句運(yùn)行期間是阻塞的;當(dāng)select中沒有case語句的時(shí)候,會(huì)阻塞當(dāng)前的groutine。所以,有人也會(huì)說select是用來阻塞監(jiān)聽goroutine的。

還有人說:select是Golang在語言層面提供的I/O多路復(fù)用的機(jī)制,其專門用來檢測多個(gè)channel是否準(zhǔn)備完畢:可讀或可寫。

以上說法都正確。

我們來回顧一下是什么是 I/O多路復(fù)用 。

每來一個(gè)進(jìn)程,都會(huì)建立連接,然后阻塞,直到接收到數(shù)據(jù)返回響應(yīng)。

普通這種方式的缺點(diǎn)其實(shí)很明顯:系統(tǒng)需要?jiǎng)?chuàng)建和維護(hù)額外的線程或進(jìn)程。因?yàn)榇蠖鄶?shù)時(shí)候,大部分阻塞的線程或進(jìn)程是處于等待狀態(tài),只有少部分會(huì)接收并處理響應(yīng),而其余的都在等待。系統(tǒng)為此還需要多做很多額外的線程或者進(jìn)程的管理工作。

為了解決圖中這些多余的線程或者進(jìn)程,于是有了"I/O多路復(fù)用"

每個(gè)線程或者進(jìn)程都先到圖中”裝置“中注冊,然后阻塞,然后只有一個(gè)線程在”運(yùn)輸“,當(dāng)注冊的線程或者進(jìn)程準(zhǔn)備好數(shù)據(jù)后,”裝置“會(huì)根據(jù)注冊的信息得到相應(yīng)的數(shù)據(jù)。從始至終kernel只會(huì)使用圖中這個(gè)黃黃的線程,無需再對額外的線程或者進(jìn)程進(jìn)行管理,提升了效率。

select的實(shí)現(xiàn)經(jīng)歷了多個(gè)版本的修改,當(dāng)前版本為:1.11

select這個(gè)語句底層實(shí)現(xiàn)實(shí)際上主要由兩部分組成: case語句 和 執(zhí)行函數(shù) 。

源碼地址為:/go/src/runtime/select.go

每個(gè)case語句,單獨(dú)抽象出以下結(jié)構(gòu)體:

結(jié)構(gòu)體可以用下圖表示:

然后執(zhí)行select語句實(shí)際上就是調(diào)用 func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) 函數(shù)。

func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) 函數(shù)參數(shù):

selectgo 返回所選scase的索引(該索引與其各自的select {recv,send,default}調(diào)用的序號位置相匹配)。此外,如果選擇的scase是接收操作(recv),則返回是否接收到值。

誰負(fù)責(zé)調(diào)用 func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) 函數(shù)呢?

在 /reflect/value.go 中有個(gè) func rselect([]runtimeSelect) (chosen int, recvOK bool) 函數(shù),此函數(shù)的實(shí)現(xiàn)在 /runtime/select.go 文件中的 func reflect_rselect(cases []runtimeSelect) (int, bool) 函數(shù)中:

那誰調(diào)用的 func rselect([]runtimeSelect) (chosen int, recvOK bool) 呢?

在 /refect/value.go 中,有一個(gè) func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) 的函數(shù),其調(diào)用了 rselect 函數(shù),并將最終Go中select語句的返回值的返回。

以上這三個(gè)函數(shù)的調(diào)用棧按順序如下:

這仨函數(shù)中無論是返回值還是參數(shù)都大同小異,可以簡單粗暴的認(rèn)為:函數(shù)參數(shù)傳入的是case語句,返回值返回被選中的case語句。

那誰調(diào)用了 func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) 呢?

可以簡單的認(rèn)為是系統(tǒng)了。

來個(gè)簡單的圖:

前兩個(gè)函數(shù) Select 和 rselect 都是做了簡單的初始化參數(shù),調(diào)用下一個(gè)函數(shù)的操作。select真正的核心功能,是在最后一個(gè)函數(shù) func selectgo(cas0 *scase, order0 *uint16, ncases int) (int, bool) 中實(shí)現(xiàn)的。

打亂傳入的case結(jié)構(gòu)體順序

鎖住其中的所有的channel

遍歷所有的channel,查看其是否可讀或者可寫

如果其中的channel可讀或者可寫,則解鎖所有channel,并返回對應(yīng)的channel數(shù)據(jù)

假如沒有channel可讀或者可寫,但是有default語句,則同上:返回default語句對應(yīng)的scase并解鎖所有的channel。

假如既沒有channel可讀或者可寫,也沒有default語句,則將當(dāng)前運(yùn)行的groutine阻塞,并加入到當(dāng)前所有channel的等待隊(duì)列中去。

然后解鎖所有channel,等待被喚醒。

此時(shí)如果有個(gè)channel可讀或者可寫ready了,則喚醒,并再次加鎖所有channel,

遍歷所有channel找到那個(gè)對應(yīng)的channel和G,喚醒G,并將沒有成功的G從所有channel的等待隊(duì)列中移除。

如果對應(yīng)的scase值不為空,則返回需要的值,并解鎖所有channel

如果對應(yīng)的scase為空,則循環(huán)此過程。

在想想select和channel做了什么事兒,我覺得和多路復(fù)用是一回事兒

分享名稱:go語言cas go語言cap函數(shù)
文章網(wǎng)址:http://www.yijiale78.com/article28/hhiejp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)網(wǎng)站制作網(wǎng)站設(shè)計(jì)品牌網(wǎng)站設(shè)計(jì)企業(yè)網(wǎng)站制作網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)