這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。## Goroutine ID 真實存在嗎?當然存在。Go 運行時一定有某種方法來跟蹤 goroutine ID。## 那我該使用它們嗎?不該。 - 原因一:https://groups.google.com/forum/#!topic/golang-nuts/Nt0hVV_nqHE - 原因二:https://groups.google.com/forum/#!topic/golang-nuts/0HGyCOrhuuI - 原因三:http://stackoverflow.com/questions/19115273/looking-for-a-call-or-thread-id-to-use-for-logging## 有沒有哪些包是我可以使用的?已有的來自 Go Team 成員的包,被評價為“[用此包者,將入地獄。](https://godoc.org/github.com/davecheney/junk/id)” 也有一些包基於 goroutine id 來建立 goroutine 本機存放區,如: - [github.com/jtolds/gls](https://github.com/jtolds/gls) - [github.com/tylerb/gls](https://github.com/tylerb/gls)但都有悖於 Go 語言的設計原則。## 最簡代碼如果讀到這裡,你仍“執迷不悟”,那麼下面就將展示如何擷取當前的 goroutine id :### Go 源碼中的駭客(Hacky)代碼下列代碼源於 Brad Fitzpatrick 的 [`http/2`](https://github.com/golang/net/blob/master/http2/gotrack.go) 庫。它被整合進了 Go 1.6 中,僅僅被用於調試而非常規開發。```gopackage mainimport ( "bytes" "fmt" "runtime" "strconv")func main() { fmt.Println(getGID())}func getGID() uint64 { b := make([]byte, 64) b = b[:runtime.Stack(b, false)] b = bytes.TrimPrefix(b, []byte("goroutine ")) b = b[:bytes.IndexByte(b, ' ')] n, _ := strconv.ParseUint(string(b), 10, 64) return n}```#### 工作原理解釋通過解析調試資訊來擷取 goroutine id 是可行的. `http/2` 庫就使用調試性的代碼來對串連進行追蹤查看。但僅僅是將 goroutine id 用於調試而已。調試資訊可以通過調用 [`runtime.Stack(buf []byte, all bool) int`](https://golang.org/pkg/runtime/#Stack) 來擷取,它會以文本形式列印堆棧資訊到緩衝區中。堆棧資訊的第一行會是如下文本: “goroutine #### […” 。這裡的 #### 就是真實的 goroutine id。剩餘代碼不過是進行一些文本操作來提取和解析堆棧資訊中的數字。### CGo 版本對應的合法代碼C 版本的代碼來自 [github.com/davecheney/junk/id](https://github.com/davecheney/junk/tree/master/id)。代碼中直接擷取了當前 goroutine 的 goid 屬性並返回它的值。檔案 `id.c````c#include "runtime.h"int64 ·Id(void) {return g->goid;}```檔案 `id.go````gopackage idfunc Id() int64```## 我該怎麼做?遠離 goroutine id 吧,並忘記它們的存在。從 Go 語言設計的角度來看,使用它們是危險的。因為幾乎所有使用的目的都是去做一些和 goroutine-local 相關的事情。而這違反了 Go 語言編程的 “[Share Memory By Communicating](https://blog.golang.org/share-memory-by-communicating)” 原則。
via: http://blog.sgmansfield.com/2015/12/goroutine-ids/
作者:Scott Mansfield 譯者:MaleicAcid 校對:polaris1119
本文由 GCTT 原創編譯,Go語言中文網 榮譽推出
本文由 GCTT 原創翻譯,Go語言中文網 首發。也想加入譯者行列,為開源做一些自己的貢獻嗎?歡迎加入 GCTT!
翻譯工作和譯文發表僅用於學習和交流目的,翻譯工作遵照 CC-BY-NC-SA 協議規定,如果我們的工作有侵犯到您的權益,請及時聯絡我們。
歡迎遵照 CC-BY-NC-SA 協議規定 轉載,敬請在本文中標註並保留原文/譯文連結和作者/譯者等資訊。
文章僅代表作者的知識和看法,如有不同觀點,請樓下排隊吐槽
850 次點擊