golang goroutine id的相关问题

来源:转载

关于goroutine id

C++ 中我们经常使用线程号来打日志,方便排查问题。golang1.4之前支持goroutine id的,但是在后面的版本将这个接口去掉了。

goroutine id主要有两个用途:

打日志,方便排查问题 因为golang是不支持Thread Local Storage,所以也可以使用goroutine id来实现Goroutine Local Storage golang 为什么去掉获取goroutine id的接口

Please don’t use goroutine local storage. It’s highly discouraged. In fact, IIRC, we used to expose Goid, but it is hidden since we don’t want people to do this.

用户经常使用goroutine id来实现 goroutine local storage,而golang不希望用户使用 goroutine local storage

when goroutine goes away, its goroutine local storage won’t be GCed. (you can get goid for the current goroutine, but you can’t get a list of all running goroutines)

为什么不建议使用goroutine local storage? goroutine local storage 不容易做GC,因为只能获取到当前goroutine的gid,而不能获取到其它goroutine的gid

what if handler spawns goroutine itself? the new goroutine suddenly loses access to your goroutine local storage. You can guarantee that your own code won’t spawn other goroutines, but in general you can’t make sure the standard library or any 3rd party code won’t do that.

用户可以自已来处理goroutine local storage,但是这样的话,很难保证全部做好。

thread local storage is invented to help reuse bad/legacy code that assumes global state, Go doesn’t have legacy code like that, and you really should design your code so that state is passed explicitly and not as global (e.g. resort to goroutine local storage)

thread local storage本来就是为了挽救垃圾代码的一种手段,所以不建议使用。

不过个人认为用来打日志时,带上thread goroutine id是非常有用的。

解决方法1:修改基础库

在 $GOPATH/src/pkg/runtime/runtime.c中添加方法:

void runtime·GetGoId(int32 ret){ ret = g->goid; USED(&ret);}

在 $GOPATH/src/pkg/runtime/extern.go 导出这个方法:

func GetGoId() int

重新编译:

cd $GOROOT/src./make.bask

使用:

package mainimport "fmt"import "runtime"func main() { fmt.Println("Id =", runtime.GetGoId())} 解决方法2:gls

一个开源的库,但是没有花时间云了解它的原理

https://github.com/jtolds/gls

参考资料

* golang-nuts

* gls

* 获取goroutine的id



分享给朋友:
您可能感兴趣的文章:
随机阅读: