溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Go語(yǔ)言中g(shù)o程釋放操作的示例分析

發(fā)布時(shí)間:2021-05-06 10:15:49 來(lái)源:億速云 閱讀:228 作者:小新 欄目:開(kāi)發(fā)技術(shù)

小編給大家分享一下Go語(yǔ)言中g(shù)o程釋放操作的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

go適合做什么

go是golang的簡(jiǎn)稱(chēng),而golang可以做服務(wù)器端開(kāi)發(fā),且golang很適合做日志處理、數(shù)據(jù)打包、虛擬機(jī)處理、數(shù)據(jù)庫(kù)代理等工作。在網(wǎng)絡(luò)編程方面,它還廣泛應(yīng)用于web應(yīng)用、API應(yīng)用等領(lǐng)域。

情況1:

Go語(yǔ)言中,若在子go程中創(chuàng)建一個(gè)新 go程,子go程釋放(銷(xiāo)毀),新創(chuàng)建的go程不會(huì)隨著子go程的銷(xiāo)毀而銷(xiāo)毀。

原因:

go程共享堆,不共享?xiàng)?,go程由程序員在go的代碼里顯示調(diào)度(釋放)。

實(shí)例:

package main
import (
	"fmt"
	"time"
	"runtime"
)
func test()  {
	for i:=0;i<10;i++{
		fmt.Printf("執(zhí)行第%d次go程\n",i)
		time.Sleep(time.Second)
	}
	fmt.Println("go程執(zhí)行完畢!")
}
func main() {
	go func() {
		go test()
		fmt.Println("------aaaaaaaa-------")
		time.Sleep(time.Second)
		fmt.Println("------go程結(jié)束--------------")
		/*
		   不管是return  還是  runtime.Goexit(),效果一樣
		*/
		//return
		runtime.Goexit()
 
	}()
	for{
		runtime.GC()
	}
}

Go語(yǔ)言中g(shù)o程釋放操作的示例分析

從以上實(shí)例來(lái)看,雖然子go程已經(jīng)退出,但是在子go程中新建的go程還在執(zhí)行!原因:go程不共享?xiàng)?,有自己?dú)立的棧空間。子go程有自己的棧,在子go程中創(chuàng)建的新go程也有自己的棧。

子go程的棧被釋放(回收),由于棧獨(dú)立,因此新創(chuàng)建的go程的棧不會(huì)被釋放。

情況2:

Go語(yǔ)言中,若在主go程中創(chuàng)建一個(gè)新 go程,主go程釋放(銷(xiāo)毀),新創(chuàng)建的go程隨著主go程的銷(xiāo)毀而銷(xiāo)毀。

原因:

go程共享堆,不共享?xiàng)?,go程由程序員在go的代碼里顯示調(diào)度(釋放)。

實(shí)例:

package main
 
import (
	"fmt"
	"time"
)
func main() {
	go func() {
		for i:=0;i<10;i++{
			fmt.Printf("子go程:執(zhí)行第%d次操作!\n",i)
			time.Sleep(time.Second)
		}
	}()
	for i:=0;i<3;i++{
		fmt.Println("--------aaaa------")
		time.Sleep(time.Second)
	}
}

Go語(yǔ)言中g(shù)o程釋放操作的示例分析

從以上實(shí)例來(lái)看,雖然主go程退出,子go程馬上退出。原因:go程共享堆。主go程和新創(chuàng)建的子go程共享一個(gè)堆。主go程退出,執(zhí)行main對(duì)應(yīng)的{ },堆退出。由于是共享堆,所以對(duì)應(yīng)的子go程也會(huì)被銷(xiāo)毀。

補(bǔ)充:go基礎(chǔ)之服務(wù)退出問(wèn)題

最近學(xué)習(xí)公司微服務(wù)的代碼,看到每一個(gè)微服務(wù)的main函數(shù)都阻塞在那里,然后里面起的goroutine一直在哪里運(yùn)行。

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) //初始化一個(gè)channel
    signal.Notify(exit, syscall.SIGINT, syscall.SIGTERM) //notify方法用來(lái)監(jiān)聽(tīng)收到的信號(hào)
    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函數(shù)的運(yùn)行。然后goroutine隨之停止運(yùn)行。

以上是“Go語(yǔ)言中g(shù)o程釋放操作的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

go
AI