2015-03-30 47 views
0

我有一個通道連接的通道,所以每個goroutine都會觸發另一個直到所有的通道都運行。放得更簡單,想象兩個門店AB,以便當A完成後,它應該告訴B它可以運行。關閉頻道與發送例如一個空的結構?

這工作正常,我已經嘗試了幾個變種,因爲我已經瞭解了更多關於pipelines in Go

目前,我有一個信令信道

ch := make(chan struct{}) 
go A(ch) 
go B(ch) 
... 

func B(ch <-chan struct{}) { 
    <-ch 
    ... 

AB塊做

func A(ch chan struct{}) { 
    defer close(ch) 
    ... 
} 

能正常工作的時候,我也試過關閉,而不是關閉,發送一個空的結構struct{} i n A()

關閉通道或發送空結構有什麼區別嗎?無論哪種方式更便宜/更快/更好?

當然,在通道中發送任何其他類型會佔用「一些」內存量,但它如何與空的結構?關閉只是通道的一部分,因此即使信息在goroutine之間傳遞,也不會「發送」。

我很清楚過早的優化。這只是爲了理解事情,而不是優化任何事情。

也許有一種慣用的Go方式來做到這一點?

感謝您對此的任何澄清!

回答

2

關閉通道表示該通道上不會有更多的發送。這通常是可取的,因爲在無意發送或關閉(編程錯誤)的情況下,您會在此之後發生恐慌。 A close也可以向多個接收器發送信號,表明沒有更多的消息,通過發送哨兵值你不能很容易地進行協調。

自然地,在通道中發送任何其他類型佔用「一些」內存量,但它是如何與空的結構?

不能保證它在一個無緩衝的通道中佔用額外的內存(這完全是一個實現細節)。發送阻塞直到接收可以繼續。

關閉只是通道的一部分,因此即使信息在goroutine之間傳遞,也不會如此「發送」。

這裏沒有優化,close只是可以發送到頻道的另一種類型的消息。

每個結構都有明確的含義,您應該使用適當的結構。

  • 如果您需要發信號通知一個接收器,並保持通道打開以發送更多值,則發送一個標記值。

  • 關閉信道,如果這是最後的消息,可能信號的多個接收器,並且這將是再次發送或接近一個錯誤。

+0

感謝您的回答。我知道什麼關閉意味着什麼,並且詢問'close(ch)'和'ch < - struct {} {}'。你有沒有提到close是一個信息,而不是頻道的屬性? – murrekatt 2015-03-30 18:15:03

+0

@murrekatt:'close'是一個合乎邏輯的消息,該承諾沒有更多的價值將被送到你認爲什麼是消息的特殊值?發送和關閉都只是操縱通道的內部狀態,導致將值發送到接收器。 – JimB 2015-03-30 18:32:17

+0

我在Go的源代碼中查看了什麼'close',並且它設置了一個標誌,指示通道已關閉。 – murrekatt 2015-03-31 07:45:09

0

您可以從多個goroutines從封閉的渠道接收,他們將永遠不會阻止。這是一個主要優勢。這是one_to_many模式

finish := make(chan struct{})可以many_to_one模式時使用多個併發選手要舉報的東西做的,外人不會panic

這不是內存消耗。

+0

@Uvelichtiel你會不會用一個等待組信號多對一完成? – murrekatt 2015-03-31 07:46:30

+0

@murrekatt同步等待用於等待所有組。但是你可以只對勝利者完成感興趣。在這種情況下,贏家不應該關閉頻道,以便外部人不會在封閉頻道上發出恐慌。運動員應該僅向裁判員表示他們已經完成並裁判員反過來關閉比賽。 – Uvelichitel 2015-03-31 11:53:11

相關問題