返回信息流比如有一个共享变量v,只有一个固定的线程t1会修改v的值,固定的线程t2,t3会读取v的值。在这个场景下,如果不加锁,就会出现race。
但是如果业务场景能够接受t2和t3读取到v的旧值,那么代码中是否可以不加锁,以取得更高的性能?
这是一条镜像帖。来源:北邮人论坛 / golang / #1822同步于 2020/6/2
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖
【问题】race是必须消除的吗?
lzj0218
2020/6/2镜像同步15 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
搜了一下,最好还是避免用这种方式。可能会导致一些严重的bug(并且很难发现),或者crash
如果你的场景是读多写少的话,可以采用 atomic.Store/Load 这样的方式,性能也不差
参考:
https://software.intel.com/content/www/us/en/develop/blogs/benign-data-races-what-could-possibly-go-wrong.html
https://groups.google.com/forum/#!topic/golang-nuts/L-bGvB52UrU
不可以,比如修改变量的操作可能不是原子的,一个64位变量的修改可能分两次,这样的话在第一次修改和第二次修改之间读取变量的话就不是旧数据,而是脏数据了
我觉得是不是还是要看该变量读和写是不是原子操作。如果读了一半或者写了一半,结果被另一个线程操作了,可能会出现非预期的结果。例如string类型,const char*类型等等。如果是普通int bool类型的话,一般读写就是一条MOV指令吧。如果写的值里再有些复杂运算的话,就不太清楚了。而且不知道是否还会有编译器优化,指令重排,中断等其他的坑在里边