3 回答

TA貢獻(xiàn)1869條經(jīng)驗(yàn) 獲得超4個(gè)贊
用于取消,如鏈接文章中所示。close()
有問(wèn)題的代碼不能保證工作。下面是它失敗的場(chǎng)景:
一個(gè)戈魯丁已準(zhǔn)備好從 接收。所有其他戈魯丁人都在其他地方忙碌。
exit
main 發(fā)送的值由準(zhǔn)備好的戈魯廷接收。
該戈魯廷向 接收的值發(fā)送一個(gè)值。
exit
main()
其他戈魯廷不會(huì)退出,因?yàn)闆](méi)有更多的值被發(fā)送到 。請(qǐng)參閱此使用時(shí)間的游樂(lè)場(chǎng)示例。滲漏以誘導(dǎo)問(wèn)題場(chǎng)景。exit
為什么總是在go例程中進(jìn)行接收,并且只有當(dāng)所有例程都完成時(shí),才會(huì)執(zhí)行帶有注釋“//Final Exit”的通道接收?
該程序的執(zhí)行方式就好像通道維護(hù)著一個(gè)有序的等待戈魯丁隊(duì)列,但規(guī)范中沒(méi)有任何內(nèi)容可以保證該行為。即使通道具有有序隊(duì)列,如果 goroutine 正在執(zhí)行某些操作而不是等待從 接收,則程序也可能會(huì)遇到上述情況。exit

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超7個(gè)贊
如果您注意到程序的輸出
In go routine 6
In go routine 0
In go routine 7
.
.
Exit received from 6
Exit received from 0
Exit received from 7
.
.
Final exit
它們以相同(或幾乎相同)的順序被調(diào)用,這些順序與它們的啟動(dòng)方式相同。如果您的 Go 例程都不繁忙,則將使用第一個(gè)注冊(cè)的例程。這只是運(yùn)行時(shí)的實(shí)現(xiàn),我不會(huì)指望這種行為。
您的最終出口是最后一個(gè)要收聽(tīng)的通道,因此最后使用它。
如果刪除時(shí)間。循環(huán)后睡覺(jué),您的最終出口幾乎會(huì)立即被調(diào)用,并且您的大多數(shù)go例程都不會(huì)收到退出信號(hào)
輸出與時(shí)間輸出。睡眠(在跑步之間會(huì)非常多)
In go routine 0
Exit received from 0
In go routine 1
In go routine 2
In go routine 3
In go routine 4
In go routine 5
In go routine 6
In go routine 7
In go routine 14
In go routine 15
In go routine 16
In go routine 17
In go routine 18
In go routine 19
Final exit

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超5個(gè)贊
請(qǐng)考慮此輕微修改。
package main
import (
"fmt"
)
func main() {
var exit chan int = make(chan int)
var workers = 20
for i := 0; i < workers; i++ {
go func(instance int) {
fmt.Println("In go routine ", instance)
for {
select {
case i := <-exit:
fmt.Println("Exit", i, "received from ", instance)
exit <- i-1
return
}
}
}(i)
}
exit <- workers
fmt.Println("Final exit:", <-exit)
}
在這里,我做了3件事:首先,為了簡(jiǎn)潔起見(jiàn),我刪除了未使用的頻道。其次,我消除了睡眠。第三,我將通道更改為每次通過(guò)都會(huì)遞減的通道。如果我傳入工作人員的數(shù)量,則除“最終”消息以外的任何值都表示工作人員被丟棄。exitint0
下面是一個(gè)運(yùn)行示例:
% go run t.go
In go routine 8
In go routine 5
In go routine 0
In go routine 2
Exit 20 received from 8
Exit 19 received from 5
Final exit: 18
In go routine 13
當(dāng)呼叫時(shí),直到睡眠結(jié)束才會(huì)安排。其他哥魯丁都有這個(gè)時(shí)間來(lái)設(shè)置他們的頻道閱讀器。我只能假設(shè),因?yàn)槲以谌魏蔚胤蕉颊也坏剿?,頻道讀者很可能在大致的時(shí)間順序錯(cuò)誤中排隊(duì) - 因此,保證讀者是最后一個(gè)。maintime.Sleepsleepmain
如果這是一致的行為,那肯定是不可靠的。
請(qǐng)參閱在一個(gè)頻道上收聽(tīng)多個(gè)戈魯丁,以獲取有關(guān)此內(nèi)容的更多想法。
- 3 回答
- 0 關(guān)注
- 89 瀏覽
添加回答
舉報(bào)