原文链接:面试官:Context携带数据是线程平安的吗?
前言
asongcontextvaluecontextcontextcontextvalue
contextvalue
contextcontextvalue
func main() {
ctx := context.WithValue(context.Background(), "asong", "test01")
go func() {
for {
_ = context.WithValue(ctx, "asong", "test02")
}
}()
go func() {
for {
_ = context.WithValue(ctx, "asong", "test03")
}
}()
go func() {
for {
fmt.Println(ctx.Value("asong"))
}
}()
go func() {
for {
fmt.Println(ctx.Value("asong"))
}
}()
time.Sleep(10 * time.Second)
}
contextcontext
func main() {
m := make(map[string]string)
m ["asong"] = "Golang梦工厂"
ctx := context.WithValue(context.Background(), "asong", m)
go func() {
for {
m1 := ctx.Value("asong")
mm := m1.(map[string]string)
mm["asong"] = "123213"
}
}()
go func() {
for {
m1 := ctx.Value("asong")
mm := m1.(map[string]string)
mm["asong"] = "123213"
}
}()
time.Sleep(10 * time.Second)
}
运行后果:
fatal error: concurrent map writes
goroutine 18 [running]:
runtime.throw({0x1072af2, 0x0})
......
为什么线程平安?
contextcontext
context.Backgroud()context.TODO()
ContextWithValuecontextWithValuecontextcontextWithValuevalueCtx
func WithValue(parent Context, key, val interface{}) Context {
if parent == nil {
panic("cannot create context from nil parent")
}
if key == nil {
panic("nil key")
}
if !reflectlite.TypeOf(key).Comparable() {
panic("key is not comparable")
}
return &valueCtx{parent, key, val}
}
valueCtx
type valueCtx struct {
Context
key, val interface{}
}
valueCtxContextkey,val
contextcontextvalueCtxcontext
keyemptyCtxnil
画个图示意一下:
contextcontextcontext
总结
context
好啦,本文到这里就完结了,我是asong,咱们下期见。
欢送关注公众号:【Golang梦工厂】