亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

理解代碼:通過交流共享資源

理解代碼:通過交流共享資源

Go
慕村9548890 2021-11-01 10:26:15
我一直在嘗試理解https://golang.org/doc/codewalk/sharemem/ 中的代碼 雖然我得到了關于通過通道傳遞資源的大部分內容,但我無法理解程序運行的無限循環. 當 poller 函數中的“in”通道(從 main 函數接收)只運行 3 個 poller go 例程時,程序如何無限執行 Poller 函數?我得到 StateMonitor 具有無限循環匿名 go 函數的想法。但是它不能在沒有從輪詢函數接收的情況下更新 LogState。我假設程序無限地執行對 url 的 Get 請求。為了確認我的理解沒有錯,我通過打開和關閉 wifi 來測試該程序,以查看日志是否發生變化。令我驚訝的是,它確實進行了幾次迭代,但之后它停止響應我的更改并繼續顯示相同的日志。那么,這是否意味著程序有問題?還是我沒有理解一些基本概念?
查看完整描述

3 回答

?
aluckdog

TA貢獻1847條經驗 獲得超7個贊

通道上的發送操作會阻塞,直到接收器可用于同一通道:如果通道上的值沒有接收器,則不能將其他值放入通道。反之亦然:當通道不為空時,不能在通道中發送新值!因此發送操作將等待直到通道再次可用。

另一方面,通道的接收操作會阻塞,直到發送方可用于同一通道:如果通道中沒有值,則接收方將阻塞。

要解鎖通道,我們需要無限循環地從通道中提取數據。

這就是程序在無限循環中發送和讀取數據的原因。


查看完整回答
反對 回復 2021-11-01
?
慕田峪7331174

TA貢獻1828條經驗 獲得超13個贊

當輪詢函數中的“in”通道(從主函數接收)僅運行 3 個輪詢 go 例程時,程序如何無限執行輪詢函數?


因此,首先該程序創建兩個輪詢器:


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

}

這段代碼似乎是無限執行的,但它通常會阻止從隊列中讀取。所以這個循環等待下一個值出現。


讓我們實際上跳過它:

  1. 有兩個 Poller 閱讀資源。

  2. 程序將第一個資源發送到隊列。

  3. 其中一個輪詢器獲取資源并開始池化。另一個等待。

  4. 在某個時刻,程序將新資源發送到隊列。

  5. 當第一個輪詢器忙時,第二個輪詢器被解除阻塞并開始輪詢。

  6. 程序發送第三個資源并在兩個輪詢器忙時阻塞。

  7. 當其中一個輪詢器完成時,它會占用最后一個資源并繼續。

  8. 同時,主程序從完整隊列中讀取值。

for r := range in { s := r.Poll() status <- State{r.url, s} out <- r }這段代碼如何無限運行?如果它在“in”通道上循環,并且“in”從掛起隊列中獲取其資源,則它應該在幾次迭代后終止。我想這正是我不明白的部分。

準確地說,in不從pending隊列中獲取資源。in  pending隊列。隊列(或通道,我可以互換使用)可以通過調用close 關閉,但直到它沒有被明確關閉,它才被認為是活動的。對它的任何讀取都會阻塞當前的 goroutine,直到給出下一個值。然后 gorotine 繼續。

我想您一直在考慮通道,就像它們是具有固定數量元素的數組一樣。他們不是??紤]到他們喜歡具有無限數量元素的數組,但具有可能引發異常的阻塞讀?。ㄈ绻皇煜み@個概念,這是關閉隊列的粗略近似值)。


查看完整回答
反對 回復 2021-11-01
  • 3 回答
  • 0 關注
  • 207 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號