我有以下設置:怎麼殺夠程
func startsMain(){
go main()
}
fun stopMain(){
//kill main
}
func main() {
//infinite loop
}
我創建一個黃瓜的步驟,我需要能夠啓動和擊落的應用。
謝謝。
我有以下設置:怎麼殺夠程
func startsMain(){
go main()
}
fun stopMain(){
//kill main
}
func main() {
//infinite loop
}
我創建一個黃瓜的步驟,我需要能夠啓動和擊落的應用。
謝謝。
你可以使用select
和頻道殺死你的無限循環!
var quit chan struct{}
func startLoop() {
quit := make(chan struct{})
go loop()
}
func stopLoop() {
// As mentioned by Kaedys
//close(quit)
// permits signalling everyone havins such a `case <-quit:`
// statement to be stopped at once, which might be even better.
quit <- struct{}{}
}
// BTW, you cannot call your function main, it is reserved
func loop() {
for {
select {
case <-quit:
break
default:
// do stuff. I'd call a function, for clarity:
do_stuff()
}
}
}
好的一塊圍棋,不是嗎?
現在,這是什麼奇怪的chan struct{}
?這是一個零大小的頻道。我們只能填充空結構(即:struct{}{}
)。它可能是chan bool
或其他任何內容,因爲我們不使用頻道的內容。重要的一點是,我們使用quit
通道來通知我們goroutine中的無限循環,以便停下來。
select
聲明用於捕捉來自聲道的內容。這是一個阻塞語句(將暫停執行,直到case
所調查的某個通道被放入某個通道爲止),除非您輸入default
語句。在這種情況下,每次執行select
時,如果內部放入了quit
或將調用do_stuff()
,則循環將中斷。如果您已經通過Go Tour,您已經知道這一點。
其他很酷的併發模式可以在Go Blog上找到。
最後,對於進一步的樂趣,你可以問你的do_stuff
功能是在固定的時間間隔使用Ticker
S,而不是消耗100%的CPU,像這樣執行:
import "time"
// [...]
func loop() {
// This ticker will put something in its channel every 2s
ticker := time.NewTicker(2 * time.Second)
for {
select {
case <-quit:
// If you don't stop it, the ticker will cause memory leaks
ticker.Stop()
break
case <-ticker.C:
// do stuff. I'd call a function, for clarity:
do_stuff()
}
}
}
這裏,select
阻止,因爲我們刪除了default
聲明。
值得注意的是,退出渠道的典型風格是「關閉()」它們,而不是通過它們發送值。這不僅在代碼中更清晰,而且封閉的通道會立即向所有偵聽器發出信號,而您必須通過通道爲每個偵聽器發送單獨的消息。另外,'main()'是默認調用的程序入口點,您不需要(我相信_can't_)將它與另一個函數分開調用。 – Kaedys
我聽說關於'close()'讓'case'被執行,我認爲是不合邏輯的。但是現在我明白了:立即向所有人發信號對我非常有用,謝謝:) –
更好的是'context'包,請參閱https://golang.org/pkg/context/您應該更改示例以使用'ctx,cancel:= context.WithCancel(context.Background())'。然後'main'可以使用'defer cancel()',goroutines可以在'ctx.Done()'通道上使用'select'來退出。 –
你不能從「外部」停止一個門廳。 goroutine必須支持某種終止信號(通常是一個信道)。但如果沒有,你不能強迫它或殺死它。 [在Go中取消阻止操作]的可能重複(http://stackoverflow.com/questions/28240133/cancel-a-blocking-operation-in-go/28240299#28240299)。 – icza
你不能簡單地殺死一個goroutine;請展示您嘗試解決的問題的示例。 – JimB
@icza,是否可以使用任何其他方式而不是goroutine來啓動和停止main? – Michael