使用go語言開發過程中,
很多情況,需要了解goroutine的執行情況,尤其在大量併發場景中,需要根據日誌跟蹤任務的執行情況,這個時候可以大致根據goroutine id來跟蹤程序執行的狀態。
在go語言中,沒有獲取goroutine id(簡稱goid)的API。
爲什麼沒有提供呢?
原因如下:
-
爲了避免採用Goroutine Id當成Thread Local Storage的Key。
強烈建議不要使用goroutine local storage。用戶經常使用GoId來實現goroutine local storage,而Go語言不希望用戶使用goroutine local storage。 -
當goroutine退出後,它的goroutine local storage 不會被GC。因爲雖然可以獲取當前goroutine的go id,但是不能獲取所有正在執行的goroutines列表。
-
thread local storage的應用是幫助重用現有那些不好(遺留)的採用全局狀態的代碼。而Go語言建議是重新設計代碼,採用顯示地傳遞狀態而不是採用全局狀態(例如採用goroutine local storage),例如使用context直接傳遞。
目前,有幾種獲取go id的方法。
下面介紹其中的一種方式goid。
package main
import (
"log"
"time"
"github.com/petermattis/goid"
)
func main() {
for i := 0; i < 10; i++ {
go routineTask()
}
time.Sleep(time.Second)
}
func routineTask() {
log.Printf("goid:%d\n", goid.Get())
}
output:
2019/12/28 23:18:36 goid:38
2019/12/28 23:18:36 goid:39
2019/12/28 23:18:36 goid:33
2019/12/28 23:18:36 goid:42
2019/12/28 23:18:36 goid:40
2019/12/28 23:18:36 goid:35
2019/12/28 23:18:36 goid:36
2019/12/28 23:18:36 goid:34
2019/12/28 23:18:36 goid:37
2019/12/28 23:18:36 goid:41
鑑於官方沒有提供獲取goid的方式,通過第三方方式獲取到goid後,除了打印日誌,不要用作其他的用處。