day03-go channal

https://mp.weixin.qq.com/s/90Evbi5F5sA1IM5Ya5Tp8w

不要通過(guò)共享內(nèi)存來(lái)通信,而要通過(guò)通信來(lái)實(shí)現(xiàn)內(nèi)存共享

并發(fā)哲學(xué):它依賴 CSP 模型,基于 channel 實(shí)現(xiàn)

1.CSP

CSP 全稱是 “Communicating Sequential Processes”, 被認(rèn)為是 Go 在并發(fā)編程上成功的關(guān)鍵因素,大多數(shù)的編程語(yǔ)言的并發(fā)編程模型是基于線程和內(nèi)存同步訪問(wèn)控制,Go 的并發(fā)編程的模型則用 goroutine 和 channel 來(lái)替代,書(shū)中提到:processes 被認(rèn)為是需要輸入驅(qū)動(dòng),并且產(chǎn)生輸出,供其他 processes 消費(fèi),processes 可以是進(jìn)程、線程、甚至是代碼塊? ?----劃重點(diǎn)


2.channal(先進(jìn)先出,能影響goroutine的阻塞和喚醒)

Goroutine 用于執(zhí)行并發(fā)任務(wù),channel 用于 goroutine 之間的同步、通信、事件通知。

選擇sync底層并發(fā)還是選擇channel

channel是Go的第一對(duì)象,通過(guò)channel go實(shí)現(xiàn)了內(nèi)存的共享,而且是多個(gè)goroutine同步和數(shù)據(jù)傳遞的重要手段


3.channel實(shí)現(xiàn)原理

channel底層結(jié)構(gòu)

同步模式(無(wú)緩沖)下,必須要使發(fā)送方和接收方配對(duì),操作才會(huì)成功,否則會(huì)被阻塞;異步模式(帶緩沖)下,緩沖槽要有剩余容量,操作才會(huì)成功,否則也會(huì)被阻塞

創(chuàng)建一個(gè)容量大小為6,類型為int的帶緩沖channel

一個(gè)內(nèi)核線程管理多個(gè)goroutine.內(nèi)核線程可以調(diào)度其他的 goroutine 來(lái)運(yùn)行,內(nèi)核線程本身不會(huì)阻塞。這就是通常我們說(shuō)的 M:N模型,M:N模型有M,P,G構(gòu)成,M是內(nèi)核線程,代表運(yùn)行g(shù)oroutine,P為調(diào)度相關(guān)的context,保存了goroutine可運(yùn)行的上下文,以及可運(yùn)行的goroutine列表,G則是待運(yùn)行的goroutine ,每個(gè)M都有一個(gè)P,

為何說(shuō)channel是安全的:當(dāng)sender向channel中發(fā)送第一條數(shù)據(jù)時(shí),對(duì)buf加鎖,然后將數(shù)據(jù)拷貝到buf中,增加sendx得值,釋放該鎖,然后receiver進(jìn)行消費(fèi),加鎖,將該buf中的數(shù)據(jù)拷貝出來(lái),增加recvx得值,釋放鎖,他并沒(méi)有做到共享鎖,而是通過(guò)這個(gè)結(jié)構(gòu)體,將內(nèi)存的值進(jìn)行拷貝的方式進(jìn)行通信

channel接收發(fā)送數(shù)據(jù)的本質(zhì) :Remember all transfer of value on the go channels happens with the copy of value.

channal happen-before:

(1 第 n 個(gè)send一定happened before第 n 個(gè)receive finished,無(wú)論是緩沖型還是非緩沖型的 channel。

(2 對(duì)于容量為 m 的緩沖型 channel,第 n 個(gè)receive一定happened before第 n+m 個(gè)send finished。

(3 對(duì)于非緩沖型的 channel,第 n 個(gè)receive一定happened before第 n 個(gè)send finished。

(4 channel close 一定happened beforereceiver 得到通知。


4.如何優(yōu)雅的關(guān)閉channel

don't close a channel from the receiver side and don't close a channel if the channel has multiple concurrent senders

(1 使用 defer-recover 機(jī)制,放心大膽地關(guān)閉 channel 或者向 channel 發(fā)送數(shù)據(jù)。即使發(fā)生了 panic,有 defer-recover 在兜底。

(2 使用 sync.Once 來(lái)保證只關(guān)閉一次。-----這個(gè)是我經(jīng)常使用的關(guān)閉方法

根據(jù) sender 和 receiver 的個(gè)數(shù),分下面幾種情況:

(1 一個(gè) sender,一個(gè) receiver? ? ? ? ? ? ---一個(gè)sender,從 sender 端關(guān)閉

(2 一個(gè) sender, M 個(gè) receiver? ? ? ? ? ?---一個(gè)sender,從 sender 端關(guān)閉

(3 N 個(gè) sender,一個(gè) reciver? ? ? ? ? ? ? ---多個(gè)sender,可以在一個(gè)reciever端發(fā)送一個(gè)停止的信號(hào)

多個(gè)sender和一個(gè)reciever

(4 N 個(gè) sender, M 個(gè) receiver? ? ? ? ?---增加中間人,代碼請(qǐng)看原文

有緩沖的channel在關(guān)閉后仍能讀出數(shù)據(jù)(v,ok := <- ch),當(dāng)ok 為false時(shí)代表數(shù)據(jù)讀完


5.channel的應(yīng)用

(1 停止信號(hào),同上面的關(guān)閉channel一樣,作出停止的信號(hào)

(2 與timer結(jié)合,做定時(shí)任務(wù)

(3 解耦生產(chǎn)方和消費(fèi)方

(4 控制并發(fā)數(shù)

limit 放在 func 內(nèi)部而不是外部,如果在外層,就是控制系統(tǒng) goroutine 的數(shù)量,可能會(huì)阻塞 for 循環(huán),影響業(yè)務(wù)邏輯。limit 其實(shí)和邏輯無(wú)關(guān),只是性能調(diào)優(yōu),放在內(nèi)層和外層的語(yǔ)義不太一樣。

結(jié)合https://zhuanlan.zhihu.com/p/27917262一起看

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容