2014-09-11 33 views
0

在Go中,go是產生goroutine的關鍵字。但是,似乎關鍵字沒有返回任何值,那麼如何檢測goroutine是否正確產生?如何檢查goroutine是否成功創建?

看來Go使用以下方法來檢查func是否成功。

value, err = myFunc(value) 

go關鍵字是否有類似的用法來檢測創建錯誤?看起來go如果失敗就會拋出一個運行時異常。

我想做一個測試,找出我可以爲CPU創建的最大goroutine數量。

+2

你的問題意味着產生一個新的goroutine可能會失敗,實際上有時會失敗。是什麼讓你認爲這個假設是真的?當然,任何事情都可能會失敗(只需拔掉CPU或RAM),但在這種情況下,您將無法檢查這些問題。對我來說,你的問題似乎在問「如何檢查'a + = 1'是否成功?」 – Volker 2014-09-11 06:20:57

+0

@Volker在給定的時間內,你可以擁有多少個goroutines是有上限的。實際上,甚至估計上限並不難。 – 2014-09-11 07:44:46

+0

Volkerless,我認爲案件不同於「a + = 1」。想象一個遊戲服務器,從客戶端到服務器的連接是很長時間的連接,所以需要維護客戶端的每個狀態,並且goroutine有自己的可以閃爍或增長的棧,所以最大的在線遊戲用戶限於goroutine的總內存使用情況。 – python 2014-09-11 10:22:13

回答

2

正如你已經知道:

value, err = myFunc(value)

是通過返回來處理異常的慣用方式內置error類型。我想你可以通過某種方式將它與檢查的異常進行比較。但就你而言,未能產生新的goroutine更多的是運行時異常。 golang如何處理這些是通過使用panics。您可以使用內置的recover()函數在代碼中處理它們,該函數將嘗試重新獲得對執行流程的控制權。如果沒有這個,panic將上升到堆棧,直到它崩潰程序。

注意recover()具有其中爲defer ED的函數被調用,這些功能被壓入到一個列表,並在它們被延遲執行的函數的結束始終稱爲 - 所以即使當panic發生他們將被打電話,讓您撥打recover()。如果你只是在你的函數結束時嘗試調用recover()(或者在你恐慌子函數後的任何地方),執行將永遠不會達到它。如果您可以處理恐慌(recover()不會返回err),以便您的程序可以實際上繼續執行,它將從引發恐慌的功能開始執行。

認爲上面的博客文章是足夠的,但如果你需要更多的例子只是在這裏評論。

此外,您的系統最有可能以RAM存儲器而非CPU爲界。

+0

感謝您的回答。所以有其他的最佳做法來檢測「去」關鍵字失敗,而不是運行時異常?因爲在C中,malloc/free這種內存不足不會拋出異常而是一個NULL指針。 – python 2014-09-11 03:01:54

+0

@python你真的不能這麼做,如果你非常偏執,那麼你可以添加很多像''this'這樣的延期(http://play.golang.org/p/VQWh7yozKx),但你真的應該別擔心。 – OneOfOne 2014-09-11 03:23:57

+4

另一個角度:'go'只是分配幾KB的一小段堆棧,並在調度器中做一些事情。如果你不能爲調度程序控制結構分配幾個KB或空間,那麼你的程序真的是非常糟糕;這種情況只能用於預防,不能從中恢復。 – twotwotwo 2014-09-11 03:31:15

1

goroutine創建(或多或少)只是一個內存分配。一般情況下你不能捕獲內存分配異常,這與goroutines是一樣的。

如果你的程序內存不足,除了退出和重新啓動之外,通常沒有什麼可以做的。

+0

hi rog,如果goroutine可以在調用失敗的情況下返回一些值,就像C++ new/malloc一樣,它通常會返回NULL指針而不是拋出異常,這聽起來很合理。如果golang遊戲服務器想要保存用戶的所有連接,那麼聽起來合理,如果「go」失敗,返回一些內容 – python 2014-09-12 02:43:36

+1

爲什麼「go」語句是特殊的?還有許多其他地方都是隱含分配的。例如,將字符串分配給接口{}進行分配 - 它怎麼會返回一個值?調用一個函數也可以分配(堆棧幀被分配)。我們不希望Go變得像C,你需要檢查每個分配。 你想讓你的測試告訴你什麼? – rog 2014-09-12 08:28:51

0

如果您正在使用的函數返回錯誤的執行例程,您可以調用匿名函數並處理匿名函數中的錯誤。

go func() { 
    value, err := myFunc() 
}()