欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Go语言 go程释放操作(退出/销毁)

程序员文章站 2022-04-12 23:01:41
情况1:go语言中,若在子go程中创建一个新 go程,子go程释放(销毁),新创建的go程不会随着子go程的销毁而销毁。原因:go程共享堆,不共享栈,go程由程序员在go的代码里显示调度(释放)。实例...

情况1:

go语言中,若在子go程中创建一个新 go程,子go程释放(销毁),新创建的go程不会随着子go程的销毁而销毁。

原因:

go程共享堆,不共享栈,go程由程序员在go的代码里显示调度(释放)。

实例:

package main
import (
	"fmt"
	"time"
	"runtime"
)
func test()  {
	for i:=0;i<10;i++{
		fmt.printf("执行第%d次go程\n",i)
		time.sleep(time.second)
	}
	fmt.println("go程执行完毕!")
}
func main() {
	go func() {
		go test()
		fmt.println("------aaaaaaaa-------")
		time.sleep(time.second)
		fmt.println("------go程结束--------------")
		/*
		   不管是return  还是  runtime.goexit(),效果一样
		*/
		//return
		runtime.goexit()
 
	}()
	for{
		runtime.gc()
	}
}

Go语言 go程释放操作(退出/销毁)

从以上实例来看,虽然子go程已经退出,但是在子go程中新建的go程还在执行!原因:go程不共享栈,有自己独立的栈空间。子go程有自己的栈,在子go程中创建的新go程也有自己的栈。

子go程的栈被释放(回收),由于栈独立,因此新创建的go程的栈不会被释放。

情况2:

go语言中,若在主go程中创建一个新 go程,主go程释放(销毁),新创建的go程随着主go程的销毁而销毁。

原因:

go程共享堆,不共享栈,go程由程序员在go的代码里显示调度(释放)。

实例:

package main
 
import (
	"fmt"
	"time"
)
func main() {
	go func() {
		for i:=0;i<10;i++{
			fmt.printf("子go程:执行第%d次操作!\n",i)
			time.sleep(time.second)
		}
	}()
	for i:=0;i<3;i++{
		fmt.println("--------aaaa------")
		time.sleep(time.second)
	}
}

Go语言 go程释放操作(退出/销毁)

从以上实例来看,虽然主go程退出,子go程马上退出。原因:go程共享堆。主go程和新创建的子go程共享一个堆。主go程退出,执行main对应的{ },堆退出。由于是共享堆,所以对应的子go程也会被销毁。

补充:go基础之服务退出问题

最近学习公司微服务的代码,看到每一个微服务的main函数都阻塞在那里,然后里面起的goroutine一直在哪里运行。

package main
import(
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "log"
    "time"
)
func testfunc() error {
    go func(){
        for{
           fmt.printf("testing....\n")
           time.sleep(time.minute)
        }
    }()
    return nil
}
func exitfunc(){
    fmt.println("i am exiting!")
}
func main(){
    logger := log.new(os.stdout, "[testgoroutine]", log.lshortfile | log.ldate | log.ltime) //初始化日志
    exit := make(chan os.signal,10) //初始化一个channel
    signal.notify(exit, syscall.sigint, syscall.sigterm) //notify方法用来监听收到的信号
    testfunc()
    sig := <-exit
    logger.printf("%s",sig.string())
    exitfunc()
}

代码输出

[root@localhost demoproject]# go run test.go

testing....

^c[testgoroutine]2018/07/31 19:26:14 test.go:36: interrupt

i am exiting!

可以看到知道按了ctrl+c之后才退出main函数的运行。然后goroutine随之停止运行。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。