zl程序教程

您现在的位置是:首页 >  其他

当前栏目

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

2023-02-26 10:20:49 时间

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

我们这篇博文讨论Go的协程杀掉自己协程的有关内容。这里我们就需要用到runtime.Goexit().

先上代码介绍runtime.Goexit()及其使用方法

(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>

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()激活,让他能够运行。

看看运行结果吧。

任务进行中... 任务进行中... ...(中间省略若干) 任务进行中...

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

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


本站部分内容转载自网络,版权属于原作者所有,如有异议请联系QQ153890879修改或删除,谢谢!
转载请注明原文链接:「让我们一起Golang」让协程自己kill自己

你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:

1、点击这里立即申请成为腾讯云VIP客户

2、点击这里立即注册成为天翼云VIP客户

3、点击这里立即申请成为华为云VIP客户

4、点击这里立享阿里云产品终身VIP优惠价

喜欢 (0)
[[email protected]]
分享 (0)