1 回答

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超9個(gè)贊
如果您愿意,您可以將頻道視為一種郵箱(可能具有特殊的傳送能力,例如游戲 Portal中的門戶)。
無緩沖通道是一個(gè)完全沒有空間容納任何包裹的郵箱。對(duì)于要郵寄包裹(發(fā)送價(jià)值)的人來說,他們必須等到收件人的手從郵箱中伸出來。然后,他們可以將包裹放入手中,手將退回郵箱,并帶走包裹。如果有其他人在排隊(duì),您必須在其他人后面排隊(duì)。
緩沖通道是一個(gè)可以容納一個(gè)或多個(gè)包的郵箱。要發(fā)送包裹,請(qǐng)排隊(duì)(如果有的話)。當(dāng)你到達(dá)隊(duì)伍的最前面時(shí),你可以看看這個(gè)盒子。如果有空間容納您的包裹,您可以將其放入并繼續(xù)處理您的事務(wù)。如果沒有,您可以等到有空間,然后將包裹放入并繼續(xù)處理您的業(yè)務(wù)。
所以有一個(gè)通用的發(fā)送模式:
如果有必要的話就排隊(duì)吧。
當(dāng)您到達(dá)隊(duì)列的頭部時(shí),如果有空間,請(qǐng)將包裹放入,否則等待空間,或者,對(duì)于無緩沖的通道,等待有人來到另一側(cè)(接收)并把手伸進(jìn)去接收。
同時(shí),如果您想從某個(gè)通道接收數(shù)據(jù),則需要排隊(duì),就像發(fā)送一樣。一旦你排在隊(duì)伍的最前面,你就可以從盒子里取出一個(gè)包裹,或者——對(duì)于無緩沖的通道——把你的手伸出盒子的另一邊,等待有人拿走。過來并在里面放一些東西。
在這個(gè)類比中,每個(gè) goroutine 就像一個(gè)人,或者一個(gè)Go gopher。如果需要,它(或他或她或您喜歡的任何代詞)可以排隊(duì),并將東西放入這些通道之一或?qū)⑵鋸倪@些通道之一中取出。你的程序從一個(gè) goroutine 開始,它調(diào)用main
.
在您的代碼中,您派生出第二個(gè) goroutine,它從 開始multiplyByTwo
。這個(gè) goroutine 等待一次,等待一個(gè)數(shù)字出現(xiàn)在通道中,或者在本例中,等待某人發(fā)送一個(gè)數(shù)字,因?yàn)橥ǖ罌]有緩沖。然后它將得到的(單個(gè))數(shù)字加倍,打印結(jié)果,然后退出/死亡/被埋葬,永遠(yuǎn)不再存在。
同時(shí),您main
等待某人接收(這將是您的第二個(gè) goroutine),直到它準(zhǔn)備好接受3
中的數(shù)字n
。那部分成功了。然后你main
等待另一個(gè)接收,以便它可以發(fā)送常量3
。
當(dāng)你main
等待的時(shí)候,你的另一個(gè) goroutine 正在做它的工作——或者可能已經(jīng)完成它的工作——然后退出?,F(xiàn)在,整個(gè)系統(tǒng)中只有一個(gè)“人”(或地鼠或其他什么),等待著第二個(gè)人——這個(gè)人不存在,也永遠(yuǎn)不會(huì)出生——來取號(hào)。底層 Go 系統(tǒng)可以判斷該事件永遠(yuǎn)不會(huì)發(fā)生,此時(shí)您會(huì)收到消息:
fatal?error:?all?goroutines?are?asleep?-?deadlock!
(這也會(huì)終止程序)。
這引入了一個(gè)新問題:如何告訴第二個(gè) goroutine 不再有數(shù)字到來?答案是您可以關(guān)閉通道,使用close
.
如果我們堅(jiān)持用郵箱進(jìn)行類比,您可以將關(guān)閉通道視為在通道的發(fā)送端放置特殊的貼紙或標(biāo)簽。這可以防止任何人進(jìn)一步輸入值。通道中的任何包裹都已經(jīng)是安全的——它們會(huì)一直留在那里,直到有人收到它們——但沒有新的包裹可以進(jìn)入。在接收方,很容易區(qū)分包裹和這個(gè)特殊貼紙之間的區(qū)別:所以當(dāng)您遇到“關(guān)閉”標(biāo)簽,您知道不會(huì)有更多的值出現(xiàn)。如果頻道沒有緩沖,您可以立即看到此貼紙。如果它是緩沖的,您必須先取出所有現(xiàn)有的包,然后才能看到它。
一般來說,發(fā)送者應(yīng)該關(guān)閉通道,以便接收者知道他們不會(huì)從中得到任何東西。(在許多特定情況下,您可以在不關(guān)閉通道的情況下逃脫。特別是,如果正在運(yùn)行的 goroutinemain
從其對(duì) 的調(diào)用返回main
,則所有其他 goroutine 或多或少會(huì)立即死亡。)
請(qǐng)注意,一旦關(guān)閉,任何發(fā)送者都無法再次關(guān)閉該通道,因此這意味著,如果您有多個(gè)發(fā)送者共享的單個(gè)通道,則只有其中一個(gè)可以關(guān)閉該通道!使這一工作正常進(jìn)行是很棘手的,因此更常見的是避免像這樣在多個(gè) write-goroutine 之間共享一個(gè)通道。
- 1 回答
- 0 關(guān)注
- 108 瀏覽
添加回答
舉報(bào)