「讓我們一起Golang」讓協程自己kill自己
我們這篇博文讨論Go的協程殺掉自己協程的有關内容。這裡我們就需要用到
runtime.Goexit()
.
先上代碼介紹
runtime.Goexit()
及其使用方法
package main
import (
"fmt"
"runtime"
"time"
)
func task051() {
defer fmt.Println("拿來吧你")
fmt.Println("曲項向天歌")
fmt.Println("白毛浮綠水")
//殺死目前所在協程
// Goexit terminates the goroutine that calls it. No other goroutine is affected.
// Goexit runs all deferred calls before terminating the goroutine. Because Goexit
// is not a panic, any recover calls in those deferred functions will return nil.
//
// Calling Goexit from the main goroutine terminates that goroutine
// without func main returning. Since func main has not returned,
// the program continues execution of other goroutines.
// If all other goroutines exit, the program crashes.
runtime.Goexit()
fmt.Println("紅掌撥清波")
}
func main() {
go func() {
fmt.Println("鵝鵝鵝")
task051()
fmt.Println("——駱賓王")
}()
// Sleep pauses the current goroutine for at least the duration d.
// A negative or zero duration causes Sleep to return immediately.
time.Sleep(time.Second)
}
如果
Goexit
殺掉它的 goroutine,其他 goroutine 也不會受到影響。
Goexit
在終止 goroutine 之前會調用所有延遲函數, 因為
Goexit
不是一個panic,而這些延遲函數中的任何調用恢複都将傳回 nil。
從主協程調用
Goexit
會終止主協程,而不會傳回主函數
func main
。 由于 主函數
func main
沒有傳回,程式會繼續執行其他 goroutine。 如果所有其他 goroutine 都終止,那麼程式就會崩潰。
在這段代碼裡面,主函數中是先開辟一條協程,先輸出《詠鵝》的第一句詩句,然後進入任務函數。該任務函數是執行在子協程中。
這段代碼的運作結果是
鵝鵝鵝
曲項向天歌
白毛浮綠水
拿來吧你
這裡“紅掌撥清波”并沒有輸出,因為它是在
runtime.Goexit()
之後的語句,而此時協程已經被自己殺死了。
但是延遲函數被執行了,
Goexit
Goexit
不是一個panic,而這些延遲函數中的任何調用恢複都将傳回 nil。是以“拿來吧你”不會輸出。
但是作者名”——駱賓王“為什麼也沒輸出呢?思考一下吧。
因為函數task051()裡面将目前協程kill掉了。而作者名”——駱賓王“因為協程已經被殺死而執行不到。
前面殺死的是子協程。
我們之前說主協程不能死,那麼我們現在殺死主協程看看會怎麼樣吧!
主協程被殺死之後,所有子協程就會亂了套,不眠不休。
我們先來看看主協程正常結束的樣子吧...
func main() {
go task061()
//主協程睡5秒
time.Sleep(5 * time.Second)
//runtime.Goexit()
}
func task061(){
for{
fmt.Println("任務進行中...")
time.Sleep(time.Second)
}
}
運作結果是:
任務進行中...
任務進行中...
任務進行中...
任務進行中...
任務進行中...
主協程睡覺睡了5秒,子協程沒睡一秒就說一句“任務進行中...”,是以當主協程結束時,主協程說五句“任務進行中...”。
現在我們殺死主協程看看會出現什麼吧!
将上面代碼塊的
runtime.Goexit()
激活,讓他能夠運作。
看看運作結果吧。
任務進行中...
任務進行中...
...(中間省略若幹)
任務進行中...
部落客等了半分鐘,子協程一直在那大喊“任務進行中...”,像極了晚上父母不在家,大喊大叫的熊孩子。