亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

檢查函數是否被作為 goroutine 調用

檢查函數是否被作為 goroutine 調用

Go
慕村225694 2023-06-26 16:59:09
有什么方法可以查明正在運行的函數是否被調用為 goroutine 嗎?現在我想知道wsEndpoint 函數是否作為 goroutine 調用(例如 go wsEndpoint(...))。我嘗試閱讀 http 包文檔,但沒有得到清晰的圖片,只是猜測處理程序將用 go 例程調用。真的嗎?
查看完整描述

1 回答

?
四季花海

TA貢獻1811條經驗 獲得超5個贊

每個函數都是從 goroutine 調用的,甚至是main()函數(稱為 goroutine?main)。

Go 中的 goroutine 沒有身份。哪個 goroutine 調用函數并不重要。

回答你的“原始”問題:

有什么方法可以查明正在運行的函數是否被調用為 goroutine 嗎?

如果我們將 this 定義為使用該go語句或不使用該語句調用的函數,那么答案是肯定的:我們可以檢查這一點。

但在此之前:我不會將此信息用于任何用途。不要編寫依賴于此的代碼,也不要編寫依賴于哪個 goroutine 調用函數的代碼。如果需要從多個 goroutine 同時訪問資源,只需使用適當的同步即可。

基本上我們可以檢查調用堆棧:相互調用的函數列表。如果該函數位于該列表的頂部,則使用它來調用它go(檢查答案末尾的注釋)。如果調用堆棧中在該函數之前還有其他函數,則從go另一個函數(位于調用堆棧中之前的函數)調用該函數,而無需使用 , 。

我們可以用來runtime.Callers()獲取調用 goroutine 的堆棧。這是我們檢查是否有其他函數調用“us”的方法:

func f(name string) {

? ? count := runtime.Callers(3, make([]uintptr, 1))

? ? if count == 0 {

? ? ? ? fmt.Printf("%q is launched as new\n", name)

? ? }

}

測試它:


func main() {

? ? f("normal")

? ? go f("with-go")


? ? func() { f("from-anon") }()

? ? func() { go f("from-anon-with-go") }()


? ? f2("from-f2")

? ? go f2("with-go-from-f2")


? ? f3("from-f3")

? ? go f3("with-go-from-f3")


? ? time.Sleep(time.Second)

}


func f2(name string) { f(name) }

func f3(name string) { go f(name) }

這將輸出(在Go Playground上嘗試):


"with-go" is launched as new

"from-anon-with-go" is launched as new

"from-f3" is launched as new

"with-go-from-f3" is launched as new

注意:基本上所有調用堆棧的“頂部”都有一個runtime.goexit()函數,這是在 goroutine 上運行的最頂層函數,也是所有 goroutine 的“退出”點。這就是為什么我們從堆棧中跳過 3 幀(0. 是runtime.Callers()它本身,1. 是f()函數,最后一個要跳過的幀是runtime.goexit())。您可以在此Go Playground中檢查包含函數和文件名+行號的完整調用堆棧。這不會改變這個解決方案的可行性,只是我們必須跳過 3 幀而不是 2 幀來判斷是f()從另一個函數調用還是通過go語句調用。

查看完整回答
反對 回復 2023-06-26
  • 1 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號