[英]Explain: Don't communicate by sharing memory; share memory by communicating
[英]Understanding the code : Sharing resources by communicating
我一直在嘗試了解https://golang.org/doc/codewalk/sharemem/中的代碼,盡管我大部分是通過通道傳遞資源,但我無法理解程序在其中運行的無限循環。當輪詢器功能的“輸入”通道(從主函數接收)僅運行3個輪詢器執行例程時,程序如何無限執行輪詢器功能?
我得到StateMonitor具有無限循環的匿名go功能的想法。 但是,如果沒有Poller函數的接收,它就無法更新LogState。 我假設程序無限執行對URL的Get請求。
為了確認我對所了解的內容沒有錯,我通過打開和關閉wifi以查看日志是否更改來測試了該程序。 令我驚訝的是,它確實進行了幾次迭代,但是此后它停止響應我的更改並繼續顯示相同的日志。 那么,這是否意味着程序存在錯誤? 還是我不了解一些基本概念?
當輪詢器功能的“輸入”通道(從主函數接收)僅運行3個輪詢器例程時,程序如何無限執行輪詢器功能?
因此,首先程序創建了兩個輪詢器:
for i := 0; i < numPollers; i++ {
go Poller(pending, complete, status)
}
然后它將三個資源發送到待處理狀態:
for _, url := range urls {
pending <- &Resource{url: url}
}
每個輪詢器從未決中讀取並輪詢資源:
for r := range in {
s := r.Poll()
status <- State{r.url, s}
out <- r
}
該代碼似乎可以無限執行,但是通常它阻止從隊列中讀取。 因此,此循環等待下一個值出現。
讓我們虛擬地超越它:
for r := range in { s := r.Poll() status <- State{r.url, s} out <- r }
此代碼如何無限運行? 如果它在“輸入”通道上循環,並且“輸入”從掛起隊列中獲取資源,則它應在幾次迭代后終止。 我認為這正是我不理解的部分。
確切地說, in
不會從pending
隊列中獲取資源。 in
被 pending
隊列。 可以通過調用close來關閉隊列(或通道,我可以互換使用),但是直到未明確關閉它為止,它才被認為是活動的。 從其中讀取的任何內容都會阻塞當前的goroutine,直到給出下一個值為止。 然后,gorotine恢復。
我想您一直在思考通道,就像它們是具有固定數量的元素的數組一樣。 他們不是。 考慮它們像具有無限數量的元素但具有阻塞讀取功能的數組,可能會引發異常(如果您不熟悉該概念,則近似於關閉隊列)。
通道上的發送操作將阻塞,直到接收器可用於同一通道:如果通道上的值沒有接收者,則無法在該通道中放置其他值。 反之亦然:當通道不為空時,通道中不會發送任何新值! 因此,發送操作將一直等到通道再次可用。
另一方面,對某個通道的接收操作會阻塞,直到發送方可用於同一通道為止:如果該通道中沒有值,則接收方將阻塞。
要解除阻塞通道,我們需要無限循環地從通道中提取數據。
這就是為什么程序在無限循環中發送和讀取數據的解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.