写点什么

「让我们一起 Golang」让协程自己 kill 自己

用户头像
Regan Yue
关注
发布于: 4 小时前
「让我们一起Golang」让协程自己kill自己

「让我们一起 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 在终止 goroutine 之前会调用所有延迟函数, 因为 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()激活,让他能够运行。


看看运行结果吧。


任务进行中...任务进行中......(中间省略若干)任务进行中...
复制代码


博主等了半分钟,子协程一直在那大喊“任务进行中...”,像极了晚上父母不在家,大喊大叫的熊孩子。

发布于: 4 小时前阅读数: 2
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
各位大佬点个赞呗!
4 小时前
回复
没有更多了
「让我们一起Golang」让协程自己kill自己