2015-05-07 56 views
2

如果在select語句內的恰當時刻沒有捕獲到通過golang中的頻道進入的數據是否可能被忽略?來自不同通道的數據是否會被忽略?

例如,讓我們說有此select語句:

for { 
    select { 
    case <-timer.C: 
     //block A 
    default: 
     // block B takes 2 seconds. 
    } 
} 

如果計時器在塊B運行結束,並阻止一個仍然在循環的下一次迭代運行或不信道的輸入數據得到丟失?

+1

在發送端,如果它是帶有空間的緩衝通道,則數據被緩衝。否則,它取決於寫入程序是否阻塞,以及它是否在重試或繼續並丟棄數據時不阻塞。另一種放棄/忽略數據的方式是讓讀者在沒有閱讀緩衝項目的情況下退出。 –

回答

3

當計時器到期時,它會在C上發送當前時間。如果當時沒有人從C讀取,則發送將被阻塞,所以它會一直等到接收到該值。在這種情況下,它將等待循環的下一次迭代。

通道被設計成一個同步機制,所以它們不需要讀寫器已經同步。

+0

小修正,'time.NewTimer'使用緩衝通道,以便它不能阻塞。它會將時間寫入緩衝區,稍後有人讀取它,或者如果定時器和通道不再被引用,它們最終會收集垃圾。 –

+0

相關,'time.NewTicker'也使用緩衝區大小爲1的通道並進行非阻塞發送。如果讀者落後(如果緩衝器已滿,則下一個滴答滴下),則記錄爲滴滴滴。 –

+0

感謝您的澄清。我沒有費心去查看源代碼以查看頻道是否被緩衝。 – andybalholm