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

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

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

pipe.go分析:

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

1.結(jié)構(gòu)分析

對外暴露的是一個構(gòu)造函數(shù)和構(gòu)造的兩個對象. 兩個對象分別暴露了方法,同時這兩個對象還有一個共同的底層對象. 實際上,這兩個對象暴露的方法是直接調(diào)用底層對象的, 那么核心還是在底層對象上,只是通過兩個對象和一個構(gòu)造方法將底層對象的細(xì)節(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結(jié)構(gòu)體中主要分兩塊:

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

3.PipeReader對外暴露的是讀/關(guān)閉

? ? 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對外暴露的是寫/關(guān)閉 

 ? ?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)
? ? }

他們的方法集都是指針接收者.具體方法的實現(xiàn)是通過pipe的方法完成的. pipe的方法更加明確:讀/獲取讀錯誤/結(jié)束讀寫并設(shè)置讀錯誤; 寫/獲取寫錯誤/結(jié)束讀寫并設(shè)置寫錯誤.思路相當(dāng)明確.

下面主要分析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是判斷讀寫有沒有結(jié)束, 第二階段處理實際的讀寫.

Read

  • 每次將讀的數(shù)量寫到讀信道

Write

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

4.寫法

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

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

5.總結(jié)

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

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

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

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

相關(guān)文章

  • Golang Gin框架實現(xiàn)多種數(shù)據(jù)格式返回結(jié)果詳解

    Golang Gin框架實現(xiàn)多種數(shù)據(jù)格式返回結(jié)果詳解

    這篇文章主要介紹了Golang Gin框架實現(xiàn)多種數(shù)據(jù)格式返回結(jié)果,我們都知道,一個完整的請求包含請求和處理請求以及結(jié)果返回三個步驟,在服務(wù)器端對請求處理完成以后,會將結(jié)果返回給客戶端,在gin框架中,支持返回多種請求數(shù)據(jù)格式,下面我們一起來看看
    2023-05-05
  • go語言 xorm框架 postgresql 的用法及詳細(xì)注解

    go語言 xorm框架 postgresql 的用法及詳細(xì)注解

    這篇文章主要介紹了go語言 xorm框架 postgresql 的用法及詳細(xì)注解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • mac下golang安裝了windows編譯環(huán)境后編譯變慢

    mac下golang安裝了windows編譯環(huán)境后編譯變慢

    這篇文章主要介紹了mac下golang安裝了windows編譯環(huán)境后編譯變慢的處理方法,非常的簡單,有相同問題的小伙伴可以參考下。
    2015-04-04
  • Golang開發(fā)中常用的代碼片段匯總

    Golang開發(fā)中常用的代碼片段匯總

    這篇文章主要給大家匯總了在Golang開發(fā)中常用的代碼片段,這些代碼片段都是在日常工作中編寫golang應(yīng)用時使用到,需要的朋友可以參考借鑒,下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • go語言文件正則表達(dá)式搜索功能示例

    go語言文件正則表達(dá)式搜索功能示例

    這篇文章主要介紹了go語言文件正則表達(dá)式搜索功能,涉及Go語言文件目錄的遍歷及正則操作相關(guān)技巧,需要的朋友可以參考下
    2017-01-01
  • Golang開發(fā)中如何解決共享變量問題

    Golang開發(fā)中如何解決共享變量問題

    Go提供了傳統(tǒng)通過共享變量,也就是共享內(nèi)存的方式來實現(xiàn)并發(fā)。這篇文章會介紹 Go提供的相關(guān)機制,對Golang共享變量相關(guān)知識感興趣的朋友一起看看吧
    2021-09-09
  • Go語言之io.ReadAtLeast函數(shù)的基本使用和原理解析

    Go語言之io.ReadAtLeast函數(shù)的基本使用和原理解析

    io.ReadAtLeast函數(shù)是Go語言標(biāo)準(zhǔn)庫提供的一個工具函數(shù),能夠從數(shù)據(jù)源讀取至少指定數(shù)量的字節(jié)數(shù)據(jù)到緩沖區(qū)中,這篇文章主要介紹了io.ReadAtLeast函數(shù)的相關(guān)知識,需要的朋友可以參考下
    2023-07-07
  • Go gin框架處理panic的方法詳解

    Go gin框架處理panic的方法詳解

    本文我們介紹下recover在gin框架中的應(yīng)用, 首先,在golang中,如果在子協(xié)程中遇到了panic,那么主協(xié)程也會被終止,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • Golang嵌入資源文件實現(xiàn)步驟詳解

    Golang嵌入資源文件實現(xiàn)步驟詳解

    在應(yīng)用程序中附帶代碼以外的其他資源可能會很有用,常用的實現(xiàn)方法是嵌入對象或數(shù)據(jù)。在數(shù)據(jù)庫中存儲數(shù)據(jù)應(yīng)用中,需要定義schema,在應(yīng)用啟動時創(chuàng)建表,但如果找不到schema文件呢?Go1.16提供embed包讓實現(xiàn)變得簡單,之前很多第三方包實現(xiàn)類似功能
    2023-01-01
  • Go reflect 反射原理示例詳解

    Go reflect 反射原理示例詳解

    這篇文章主要為大家介紹了Go reflect 反射原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11

最新評論