我有一部分頻道都收到相同的消息:func broadcast(c <-chan string, chans []chan<- string) { for msg := range c { for _, ch := range chans { ch <- msg } }}但是,由于每個通道chans都可能以不同的速率被讀取,因此當我遇到慢消費者時,我不想阻止其他通道。我已經用 goroutines 解決了這個問題:func broadcast(c <-chan string, chans []chan<- string) { for msg := range c { for _, ch := range chans { go func() { ch <- msg }() } }}但是,傳遞到每個通道的消息的順序很重要。我查看了規范以查看通道在阻塞時是否保持順序,我發現的是:如果容量大于零,則通道是異步的:如果緩沖區未滿(發送)或非空(接收),則通信操作成功而不會阻塞,并且元素按發送順序接收。對我來說,如果寫入被阻塞,那么它不是“發送”,而是等待發送。有了這個假設,當多個 goroutines 在寫入時被阻塞時,上面沒有說明發送的順序。通道解除阻塞后,是否有任何關于發送順序的保證?
3 回答

肥皂起泡泡
TA貢獻1829條經驗 獲得超6個贊
在此代碼中,沒有任何保證。
給定示例代碼的主要問題不在于通道行為,而在于創建的眾多 goroutine。所有的 goroutine 都在同一個疊片循環中“觸發”而無需進一步同步,因此即使在它們開始發送消息之前,我們也不知道哪些將首先執行。
然而,這通常會引發一個合理的問題:如果我們以某種方式保證幾個阻塞發送指令的順序,我們是否保證以相同的順序接收它們?
發送的“發生在之前”屬性很難創建。我擔心這是不可能的,因為:
在發送指令之前任何事情都可能發生:例如,其他 goroutine 是否執行自己的發送
在發送中被阻塞的 goroutine 不能同時管理其他類型的同步
例如,如果我有 10 個編號為 1 到 10 的 goroutine,我無法讓它們以正確的順序同時將自己的編號發送到通道。我所能做的就是使用各種順序技巧,例如在 1 個單獨的 goroutine 中進行排序。

aluckdog
TA貢獻1847條經驗 獲得超7個贊
不,沒有任何保證。
即使通道未滿,如果兩個 goroutine 大約在同一時間啟動并發送給它,我認為無法保證首先啟動的 goroutine 會真正先執行。所以你不能指望消息按順序到達。
- 3 回答
- 0 關注
- 328 瀏覽
添加回答
舉報
0/150
提交
取消