2 回答

TA貢獻1866條經(jīng)驗 獲得超5個贊
你的結(jié)果是完全合理的。由于 goroutine 相互獨立運行,您永遠不會知道 goroutine 何時開始執(zhí)行。只要行
m[2] = "Second Value"
執(zhí)行后,它將反映在您的主要 go 例程中。
因此,當(dāng)在程序的第一次和第二次打印之間執(zhí)行上述行時,您會看到結(jié)果為
1-First Value
2-Second Value
3-Second Value
4-Second Value
當(dāng)它不是你看到另一個。在第三次打印之前,您確保其他 go 例程已完成。
如果你稍微修改你的程序,只是為了更清除它
package main
import "fmt"
import "time"
func main() {
m := make(map[int]string)
m[2] = "First Value"
c := make(chan bool)
go func() {
m[2] = "Second Value"
c <- true
}()
time.Sleep(time.Second)
fmt.Printf("1-%s\n", m[2])
fmt.Printf("2-%s\n", m[2])
_ = <-c
fmt.Printf("3-%s\n", m[2])
fmt.Printf("4-%s\n", m[2])
}
Playground
您很可能會得到以下輸出
1-Second Value
2-Second Value
3-Second Value
4-Second Value
希望能幫助到你。

TA貢獻1856條經(jīng)驗 獲得超17個贊
您的代碼實際上只是確保第三次和第四次打印顯示第二個值。當(dāng)您將通道更改為緩沖區(qū)為 1 時,它并沒有真正改變?nèi)魏螙|西。
那么我們來看第一種情況。您有一個無緩沖的頻道。您觸發(fā)的 go 例程會更改地圖的內(nèi)容。但是您不知道調(diào)度程序何時會運行它。這就是為什么有時您會看到一個結(jié)果,而有時會看到另一個結(jié)果。call:_ = <-c
將確保 go 例程已經(jīng)運行。因為這個調(diào)用會阻塞,直到 go 例程實際在通道上寫了一些東西。這就是為什么您永遠不會在最后 2 次打印中看到“第一個值”的原因。
當(dāng)您使用緩沖通道時,唯一會改變的是 go 例程將在寫入通道后立即退出。沒有別的(在Effective Go上閱讀)。
- 2 回答
- 0 關(guān)注
- 232 瀏覽
添加回答
舉報