3 回答

TA貢獻(xiàn)1873條經(jīng)驗(yàn) 獲得超9個(gè)贊
可以將通道設(shè)置為對(duì)接收該通道的任何人都是只讀的,而發(fā)送方仍具有一個(gè)雙向通道,他們可以向其寫入。例如:
func F() <-chan int {
// Create a regular, two-way channel.
c := make(chan int)
go func() {
defer close(c)
// Do stuff
c <- 123
}()
// Returning it, implicitely converts it to read-only,
// as per the function return value.
return c
}
呼叫的人F()都會(huì)收到一個(gè)只能閱讀的頻道。這對(duì)于避免在編譯時(shí)潛在地濫用通道很有用。因?yàn)橹蛔x/只寫通道是不同的類型,所以編譯器可以使用其現(xiàn)有的類型檢查機(jī)制來確保調(diào)用者不會(huì)嘗試將內(nèi)容寫入沒有業(yè)務(wù)寫入的通道。

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超4個(gè)贊
我認(rèn)為只讀頻道的主要?jiǎng)訖C(jī)是為了防止腐敗和對(duì)該頻道的恐慌。想象一下您是否可以寫入由返回的通道time.After
。這可能會(huì)弄亂很多代碼。
另外,如果您發(fā)生恐慌,您可能會(huì):
關(guān)閉頻道不止一次
寫入關(guān)閉的頻道
這些操作是只讀通道的編譯時(shí)錯(cuò)誤,但是當(dāng)多個(gè)go-routine可以寫入/關(guān)閉通道時(shí),它們可能會(huì)導(dǎo)致討厭的競(jìng)爭(zhēng)狀況。
解決此問題的一種方法是永遠(yuǎn)不要關(guān)閉通道并讓它們被垃圾回收。但是,close
這不僅用于清理,而且在通道范圍超過以下范圍時(shí),它實(shí)際上也很有用:
func consumeAll(c <-chan bool) {
for b := range c {
...
}
}
如果該通道從未關(guān)閉,則該循環(huán)將永遠(yuǎn)不會(huì)結(jié)束。如果有多個(gè)go-routine正在寫入一個(gè)通道,那么必須進(jìn)行很多記賬工作,然后再?zèng)Q定哪個(gè)程序?qū)㈥P(guān)閉該通道。
由于您無法關(guān)閉只讀通道,因此可以更輕松地編寫正確的代碼。正如@jimt在他的評(píng)論中指出的那樣,您不能將只讀通道轉(zhuǎn)換為可寫通道,因此可以確保只有有權(quán)訪問通道的可寫版本的部分代碼才能關(guān)閉/寫入該通道。
編輯:
至于擁有多個(gè)閱讀器,這完全可以,只要您考慮就可以了。在生產(chǎn)者/消費(fèi)者模型中使用時(shí),這尤其有用。例如,假設(shè)您有一個(gè)僅接受連接并將其寫入工作線程隊(duì)列的TCP服務(wù)器:
func produce(l *net.TCPListener, c chan<- net.Conn) {
for {
conn, _ := l.Accept()
c<-conn
}
}
func consume(c <-chan net.Conn) {
for conn := range c {
// do something with conn
}
}
func main() {
c := make(chan net.Conn, 10)
for i := 0; i < 10; i++ {
go consume(c)
}
addr := net.TCPAddr{net.ParseIP("127.0.0.1"), 3000}
l, _ := net.ListenTCP("tcp", &addr)
produce(l, c)
}
您的連接處理可能比接受新連接需要更長(zhǎng)的時(shí)間,因此您希望擁有一個(gè)生產(chǎn)者的多個(gè)使用者。多個(gè)生產(chǎn)者比較困難(因?yàn)槟枰獏f(xié)調(diào)關(guān)閉通道的人員),但是您可以在通道發(fā)送中添加某種信號(hào)量樣式的通道。

TA貢獻(xiàn)1833條經(jīng)驗(yàn) 獲得超4個(gè)贊
Go通道基于Hoare的通信順序過程建模,Hoare的通信順序過程是并發(fā)的過程代數(shù),它以通信參與者(小“ a”)之間的事件流為中心。這樣,通道之所以具有方向性,是因?yàn)樗鼈兙哂邪l(fā)送端和接收端,即事件的產(chǎn)生者和事件的使用者。Occam和Limbo也使用了類似的模型。
這很重要-如果通道端可以在不同時(shí)間任意用作發(fā)送者和接收者,則很難為死鎖問題辯解。
- 3 回答
- 0 關(guān)注
- 311 瀏覽
添加回答
舉報(bào)