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

Go語言io?pipe源碼分析詳情

 更新時間:2022年02月09日 10:01:24   作者:zwf193071  
這篇文章主要介紹了Go語言io?pipe源碼分析詳情,pipe是一個適配器,用于連接Reader和Writer,pipe的方法不多,新的寫法卻不少,并且結構體分兩塊,讀寫信道和結束標識,下面進入文章了解具體的內容吧

pipe.go分析:

  • 這個文件使用到了errors包,也是用到了sync庫.
  • 文件說明:pipe是一個適配器,用于連接Reader和Writer.

1.結構分析

對外暴露的是一個構造函數和構造的兩個對象. 兩個對象分別暴露了方法,同時這兩個對象還有一個共同的底層對象. 實際上,這兩個對象暴露的方法是直接調用底層對象的, 那么核心還是在底層對象上,只是通過兩個對象和一個構造方法將底層對象的細節(jié)隱藏了.

2.pipe sruct分析

pipe的方法不多,新的寫法卻不少.   

 type atomicError struct{ v atomic.Value }

? ? func (a *atomicError) Store(err error) {
? ? ? a.v.Store(struct{ error }{err})
? ? }
? ? func (a *atomicError) Load() error {
? ? ? err, _ := a.v.Load().(struct{ error })
? ? ? return err.error
? ? }

atomicError提供了error的原子讀寫. 

? type pipe struct {
? ? ? wrMu sync.Mutex // Serializes Write operations
? ? ? wrCh chan []byte
? ? ? rdCh chan int

? ? ? once sync.Once // Protects closing done
? ? ? done chan struct{}
? ? ? rerr atomicError
? ? ? werr atomicError
? ? }

可以看到pipe結構體中主要分兩塊:

  • 讀寫信道
    • 兩個無緩沖信道
    • 一個互斥量(保護暴露的寫函數)
  • 結束標識
    • once保證done的關閉只執(zhí)行一次
    • done標志整個讀寫的結束
    • 剩下兩個用于存儲讀寫錯誤
    • PipeReader/PipeWriter的分析

3.PipeReader對外暴露的是讀/關閉

? ? type PipeReader struct {
? ? ? p *pipe
? ? }

? ? func (r *PipeReader) Read(data []byte) (n int, err error) {
? ? ? return r.p.Read(data)
? ? }

? ? func (r *PipeReader) Close() error {
? ? ? return r.CloseWithError(nil)
? ? }

? ? func (r *PipeReader) CloseWithError(err error) error {
? ? ? return r.p.CloseRead(err)
? ? }

PipeWriter對外暴露的是寫/關閉 

 ? ?type PipeWriter struct {
? ? ? ?p *pipe
? ? ?}

? ? func (w *PipeWriter) Write(data []byte) (n int, err error) {
? ? ? return w.p.Write(data)
? ? }

? ? func (w *PipeWriter) Close() error {
? ? ? return w.CloseWithError(nil)
? ? }

? ? func (w *PipeWriter) CloseWithError(err error) error {
? ? ? return w.p.CloseWrite(err)
? ? }

他們的方法集都是指針接收者.具體方法的實現是通過pipe的方法完成的. pipe的方法更加明確:讀/獲取讀錯誤/結束讀寫并設置讀錯誤; 寫/獲取寫錯誤/結束讀寫并設置寫錯誤.思路相當明確.

下面主要分析pipe的讀寫 

 ? func (p *pipe) Read(b []byte) (n int, err error) {
? ? ? select {
? ? ? case <-p.done:
? ? ? ? return 0, p.readCloseError()
? ? ? default:
? ? ? }

? ? ? select {
? ? ? case bw := <-p.wrCh:
? ? ? ? nr := copy(b, bw)
? ? ? ? p.rdCh <- nr
? ? ? ? return nr, nil
? ? ? case <-p.done:
? ? ? ? return 0, p.readCloseError()
? ? ? }
? ? }

? ? func (p *pipe) Write(b []byte) (n int, err error) {
? ? ? select {
? ? ? case <-p.done:
? ? ? ? return 0, p.writeCloseError()
? ? ? default:
? ? ? ? p.wrMu.Lock()
? ? ? ? defer p.wrMu.Unlock()
? ? ? }

? ? ? for once := true; once || len(b) > 0; once = false {
? ? ? ? select {
? ? ? ? case p.wrCh <- b:
? ? ? ? ? nw := <-p.rdCh
? ? ? ? ? b = b[nw:]
? ? ? ? ? n += nw
? ? ? ? case <-p.done:
? ? ? ? ? return n, p.writeCloseError()
? ? ? ? }
? ? ? }
? ? ? return n, nil
? ? }

讀寫都是利用兩個階段的select來完成,第一個階段的select是判斷讀寫有沒有結束, 第二階段處理實際的讀寫.

Read

  • 每次將讀的數量寫到讀信道

Write

  • 先將緩沖寫到寫信道,再從讀信道中獲取讀字節(jié)數,最后調整緩沖
  • 如果緩沖太大,一次讀沒讀完,就將寫的過程多來幾遍,知道緩沖全部寫完

4.寫法

PipeWriter/PipeReader對外暴露的關閉,其實只可以保留一個CloseWithError, 但是為了方便客戶(調用者),還是拆成兩個,其實可以做測試比較一下. 性能測試發(fā)現拆成兩個或寫成一個可選參函數,性能上差別不大, 那這種寫法的主要作用是讓暴露的方法更加清晰易懂.

pipe.Write中,for循環(huán)帶有once參數,可以保證循環(huán)至少來一次, 算是do while的一種實現.

5.總結

不管是PipeReader/PipeWriter,還是pipe,都對Reader/Writer有(部分)實現.

另外還有一些細節(jié)沒有說道:讀寫錯誤和EOF.

反思:本次閱讀是先理代碼后看文檔,才發(fā)現關于error部分沒有留心到, 后面還是先文檔后代碼,這樣效率會高一點.

到此這篇關于Go語言io pipe源碼分析詳情的文章就介紹到這了,更多相關Go語言io pipe源碼分析內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Golang操作DuckDB實戰(zhàn)案例分享

    Golang操作DuckDB實戰(zhàn)案例分享

    DuckDB是一個嵌入式SQL數據庫引擎,它與眾所周知的SQLite非常相似,但它是為olap風格的工作負載設計的,DuckDB支持各種數據類型和SQL特性,憑借其在以內存為中心的環(huán)境中處理高速分析的能力,它迅速受到數據科學家和分析師的歡迎,在這篇博文中,我們將探索在Go中使用DuckDB
    2025-01-01
  • 詳解go中的引用類型

    詳解go中的引用類型

    這篇文章主要介紹了go中的引用類型,文中給大家提到了值類型和引用類型的區(qū)別,通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Go語言中兩個比較流行的緩存庫使用示例

    Go語言中兩個比較流行的緩存庫使用示例

    緩存是計算機科學中的一個重要概念,設想某個組件需要訪問外部資源,它向外部源請求資源,接收并使用資源,這些步驟都需要花費時間,下面這篇文章主要給大家介紹了關于Go語言中兩個比較流行的緩存庫使用的相關資料,需要的朋友可以參考下
    2024-04-04
  • Go語言服務器開發(fā)實現最簡單HTTP的GET與POST接口

    Go語言服務器開發(fā)實現最簡單HTTP的GET與POST接口

    這篇文章主要介紹了Go語言服務器開發(fā)實現最簡單HTTP的GET與POST接口,實例分析了Go語言http包的使用技巧,需要的朋友可以參考下
    2015-02-02
  • Golang 協(xié)程配合管道的實現示例

    Golang 協(xié)程配合管道的實現示例

    本文主要介紹了Golang協(xié)程配合管道的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • GO常見的錯誤99%程序員會遇到(解決方法)

    GO常見的錯誤99%程序員會遇到(解決方法)

    這篇文章主要介紹了GO常見的錯誤99%程序員會遇到,本文給出了解決方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • golang beyla采集trace程序原理源碼解析

    golang beyla采集trace程序原理源碼解析

    beyla支持通過ebpf,無侵入的、自動采集應用程序的trace信息,本文以golang的nethttp為例,講述beyla對trace的采集的實現原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2024-02-02
  • Go操作Kafka的實現示例(kafka-go)

    Go操作Kafka的實現示例(kafka-go)

    本文介紹了使用kafka-go庫在Go語言中與Kafka進行交互,涵蓋了kafka-go的安裝、API使用、消息發(fā)送與消費方法,以及如何通過DockerCompose快速搭建Kafka環(huán)境,文章還比較了其他兩個常用的Kafka客戶端庫,感興趣的可以了解一下
    2024-10-10
  • go語言中range用法

    go語言中range用法

    這篇文章主要介紹了go語言中range用法,實例分析了Go語言中range的功能及使用技巧,需要的朋友可以參考下
    2015-03-03
  • 徹底理解golang中什么是nil

    徹底理解golang中什么是nil

    這篇文章主要介紹了golang中的nil用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評論

四平市| 道真| 舟曲县| 齐齐哈尔市| 陵水| 丽水市| 江油市| 岢岚县| 盱眙县| 天台县| 柯坪县| 中宁县| 贵州省| 常宁市| 吴江市| 穆棱市| 偏关县| 和硕县| 兴义市| 上栗县| 三河市| 大新县| 建瓯市| 都安| 镇坪县| 怀化市| 交口县| 商丘市| 彭水| 陵川县| 西林县| 阳原县| 上思县| 高陵县| 柳江县| 博乐市| 海淀区| 阿城市| 沅江市| 堆龙德庆县| 故城县|