golang src pipe.goを読んでパイプの仕組みを理解すると、私はこれらの2つのwrite()& read()関数を調べました。読者がread()funcを呼び出してl.lockを保持してからデータを待っていると、ライターはwrite()funcを呼び出してl.lockを取得してデータを書き込むのはどうですか?io.Pipe Write()およびRead()関数はどのように機能しますか?
func (p *pipe) write(b []byte) (n int, err error) {
// pipe uses nil to mean not available
if b == nil {
b = zero[:]
}
// One writer at a time.
p.wl.Lock()
defer p.wl.Unlock()
p.l.Lock()
defer p.l.Unlock()
if p.werr != nil {
err = ErrClosedPipe
return
}
p.data = b
p.rwait.Signal()
for {
if p.data == nil {
break
}
if p.rerr != nil {
err = p.rerr
break
}
if p.werr != nil {
err = ErrClosedPipe
break
}
p.wwait.Wait()
}
n = len(b) - len(p.data)
p.data = nil // in case of rerr or werr
return
}
読み:
func (p *pipe) read(b []byte) (n int, err error) {
// One reader at a time.
p.rl.Lock()
defer p.rl.Unlock()
p.l.Lock()
defer p.l.Unlock()
for {
if p.rerr != nil {
return 0, ErrClosedPipe
}
if p.data != nil {
break
}
if p.werr != nil {
return 0, p.werr
}
p.rwait.Wait()
}
n = copy(b, p.data)
p.data = p.data[n:]
if len(p.data) == 0 {
p.data = nil
p.wwait.Signal()
}
return
}
私はsync.Condについてよく分かりませんが、 'p.rwait.L =&p.l'と' p.wwait.L =&p.l'は興味深いです。待っている/シグナルのペアが私には分かりません。 – captncraig