<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
pipe.go分析:
對外暴露的是一個建構函式和構造的兩個物件. 兩個物件分別暴露了方法,同時這兩個物件還有一個共同的底層物件. 實際上,這兩個物件暴露的方法是直接呼叫底層物件的, 那麼核心還是在底層物件上,只是通過兩個物件和一個構造方法將底層物件的細節隱藏了.
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結構體中主要分兩塊:
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
- 先將緩衝寫到寫通道,再從讀通道中獲取讀位元組數,最後調整緩衝
- 如果緩衝太大,一次讀沒讀完,就將寫的過程多來幾遍,知道緩衝全部寫完
PipeWriter/PipeReader
對外暴露的關閉,其實只可以保留一個CloseWithError
, 但是為了方便客戶(呼叫者),還是拆成兩個,其實可以做測試比較一下. 效能測試發現拆成兩個或寫成一個可選參函數,效能上差別不大, 那這種寫法的主要作用是讓暴露的方法更加清晰易懂.
pipe.Write
中,for迴圈帶有once引數,可以保證迴圈至少來一次, 算是do while的一種實現.
不管是PipeReader/PipeWriter,還是pipe,都對Reader/Writer有(部分)實現.
另外還有一些細節沒有說道:讀寫錯誤和EOF.
反思:本次閱讀是先理程式碼後看檔案,才發現關於error部分沒有留心到, 後面還是先檔案後程式碼,這樣效率會高一點.
到此這篇關於Go語言io pipe原始碼分析詳情的文章就介紹到這了,更多相關Go語言io pipe原始碼分析內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45