2010-06-28 106 views
2

所以,現在,我只是傳遞一個指向Queue對象的指針(實現並不重要),並在goroutine的末尾調用queue.add(result),它應該將事物添加到隊列。添加頻道結果到隊列完成的更習慣的方式

我需要相同類型的功能 - 當然,使用逗號ok語法執行循環檢查完成在性能方面與簡單隊列添加函數調用相比是不可接受的。

有沒有辦法做到這一點更好,或不?

+0

你想要完成什麼?從我可以看到你不需要隊列對象,只是一個通道。然後在每個goroutine的結尾做channel < - 結果。 – cthom06 2010-06-28 18:59:43

+0

好吧,我有渠道生成需要一些時間來創建的對象;這些對象中的幾個一直在生成(通過循環)。創建對象後,我需要將它放到隊列中,以便程序的另一部分可以在單獨的goroutine中不斷地執行這些完成的goroutine。我明白'channel < - result'是阻塞的 - 這實際上並不是我想要的。 – 2010-06-28 19:14:19

+2

通道可以被緩衝,make(chan rtype,BUFFER_SIZE),在這種情況下,發送不會被阻塞,除非緩衝區已滿。如果你真的需要一個無限緩衝的隊列,那麼有一個帶有小緩衝區的結果通道,另一個goroutine從通道讀取並將結果存儲在一個容器/ vector.Vector – cthom06 2010-06-29 11:51:52

回答

1

你的問題實際上有兩個部分:如何在Go中排隊數據,以及如何在沒有阻塞的情況下使用通道。

對於第一部分,聽起來好像你需要做的不是使用通道向隊列中添加內容,而是使用通道作爲隊列。例如:

var (
    ch = make(chan int) // You can add an int parameter to this make call to create a buffered channel 

    // Do not buffer these channels! 
    gFinished = make(chan bool) 
    processFinished = make(chan bool) 
) 
func f() { 
    go g() 
    for { 
     // send values over ch here... 
    } 
    <-gFinished 
    close(ch) 
} 
func g() { 
    // create more expensive objects... 
    gFinished <- true 
} 
func processObjects() { 
    for val := range ch { 
     // Process each val here 
    } 
    processFinished <- true 
} 
func main() { 
    go processObjects() 
    f() 
    <-processFinished 
} 

至於如何才能使這更異步的,你可以(如cthom06指出的)傳遞給make調用第二行,這將使發送異步操作,直到通道的緩衝區中的第二個整數已滿。

編輯:但是(因爲cthom06也指出),因爲你有兩個goroutines寫入通道,其中一個必須負責關閉通道。另外,我之前的修訂版會在processObjects完成之前退出。我選擇同步goroutine的方式是創建一個更多的通道來傳遞虛擬值,以確保清理完成正確。這些通道是專門無緩衝的,以便發送以鎖步方式發送。