在PHP中,通道(channel)是一種用于并發編程的重要概念。它允許不同的協程(goroutine)之間進行通信和同步操作。然而,有一個常見的疑問是:“為什么通道不采用最后聲明的值?”這個問題涉及到通道的設計原則和使用方式。通道在接收操作時,會阻塞等待發送方發送數據。當發送方發送完數據后,接收方才能繼續執行。因此,通道的值是在發送方發送數據時確定的,而不是在接收方接收數據時確定的。這是為了保證通信的可靠性和一致性。所以,即使最后聲明的值在接收方接收時已經改變,通道仍然會采用發送時的值。這樣做可以避免數據的不一致性和混亂,確保通信的可靠性和準確性。
問題內容
我正在嘗試了解頻道。在這段代碼中,我聲明了從 1 到 10 的值。最終聲明的值為 10,但是當我打印它時,它總是返回 before(8) 之前兩個聲明的值。如果有人能解釋一下,我會很高興。
func main() { channel := make(chan int, 3) isOver := make(chan bool) go func() { for val := range channel { fmt.Println(val) } isOver <- true }() channel <- 1 channel <- 2 channel <- 3 channel <- 4 channel <- 5 channel <- 6 channel <- 7 channel <- 8 channel <- 9 channel <- 10 close(channel) fmt.Println("Channel Value is: ", <-channel) <-isOver }
登錄后復制
當我將聲明更改為 8 時,它返回之前兩個聲明的值,即 6。
解決方法
因為你為通道設置了3個緩沖區大小!
注意:您的示例在不同的操作系統中具有不同的輸出(例如我得到 Channel 值為:0
)
設置時間。在代碼中休眠看看會發生什么。在您的代碼中:
func main() {
channel := make(chan int)
isOver := make(chan bool)
go func() {
for val := range channel {
fmt.Println(val)
// sleep 1 second
time.Sleep(1 * time.Second)
}
isOver <- true
}()
channel <- 1
channel <- 2
channel <- 3
channel <- 4
channel <- 5
channel <- 6
channel <- 7
channel <- 8
channel <- 9
channel <- 10
close(channel)
fmt.Println("Channel Value is: ", <-channel)
<-isOver
}
登錄后復制
輸出為:
1 2 3 4 5 6 7 Channel Value is: 8 9 10
登錄后復制
注意:了解代碼中發生的情況的更好方法是逐步跟蹤代碼。
發生了什么?
看到這個痕跡:
1 // print 1 and sleep 1s 2,3,4 // stop for get values 3,4 // print 2 and sleep 1 3,4,5 // stop for get value 4,5 // print 3 and sleep 1 4,5,6 // stop for get value 5,6 // print 4 and sleep 1 5,6,7 // stop for get value 6,7 // print 5 and sleep 1 6,7,8 // stop for get value 7,8 // print 6 and sleep 1 7,8,9 // stop for get value 8,9 // print 7 and sleep 1 8,9,10 // stop for get value // close channel // in this line get value : fmt.Println("Channel Value is: ", <-channel) 9,10 // before get value 10 // get 9 and sleep 1 // get 10 and sleep 1 // isdone send signal true
登錄后復制
在跟蹤代碼中,當通道獲取樹值 8,9,10 時,通道關閉,在第 2 步中發生了事情:
1 – 如果 goroutine 快速獲取所有值(通道值是:0)
2 – 如果 goroutine 繁忙(通道值為:7 或 8 或 9 或 10)
有關詳細信息,請參閱此問題:何時使用緩沖通道
并查看此網站以更好地理解:鏈接