smallnest
smallnest
> @fastcgi > 如果想在 Metadata上加一个 发现并发读写的功能要怎么做呢? 多种方式,你可以参考map的实现。 或者设置一个 `var flag uint32`, 读写之前使用atomic CAS, 读写完重置为0。 如果CAS false则说明有其它goroutine正在读写它
> @GitHubSi > 有一点没有看明白,还请大家帮忙解释一下: > > 当向map中插入新的之前不存在的记录时,会向dirty中写入这个记录,同时会将read中没有删除的记录拷贝到dirty中。因为后续当miss次数过多的时候,dirty会替换掉read。 > > 但是在delete操作的时候,我发现只删除了read中的值,没有对dirty进行处理。这样如果后续进行miss切换的时候,之前删除掉的值不是就又出现了吗? > 因为read和dirty指向同一个元素。 在read中标记了相当于在dirty中也标记了
> 有点意思,另外,可能出现读写性能不平衡的情况,一般都是负责读并处理的一方,应该可以读取后并发处理来提高消费速度 嗯,后面的处理可以采用 Reactor 模式, 一个消费者负责读取,然后交给多个worker异步的处理。
> 怎么感觉像rust学习了。 嗯,功能上和rust一样了
> 和 `runtime.KeepAlive()` 用途类似吗? 不太一样。 `runtime.KeepAlive()` 保证不会被垃圾回收,但是对象的地址可能会有变化,从一个位置移动到了另外一个位置. `Pin`保证的是对象不会被运行时移动,这样对象的地址就会保持不变,可以为cgo, unsafe安全的处理
> 从截图上看,nanosleep实际休眠时间的单位是微秒,nanosleep比time.Sleep还不精确? good finds, 的确是你说的这样。这个还得好好研究研究
正确答案加上了,回答的还不错。 > @PureWhiteWu > 1. D > 2. D > 3. D > 4. B > 5. D > 6. 不熟悉Pool,不知道…… > 7. C > 8. D > 9. A...
因为o.Done没有保护,通过atomic可以保证多CPU情况下不会有问题。 类似的Java的双检查要求变量使用volatile声明。可以和Once的实现代码对照 > @PureWhiteWu > 鸟哥求教一下,为什么第四题是C呢? @smallnest
IA64情况下也是有问题的,因为Lock并没有保护着第13行的读,所以即使本goroutine设置了`done =1`,其它的goroutine在这个时候还是可能读取到`done == 0`,所以必须通过atomic保证happen before关系(atomic基本可以认为保证happen before,虽然官方没有明确保证,但是认为目前使用起来还没遇到过问题) > @PureWhiteWu > 有道理,之前只考虑了IA64平台上的情况,在其它平台上不能保证没问题,多谢! > > @smallnest > > 因为o.Done没有保护,通过atomic可以保证多CPU情况下不会有问题。 类似的Java的双检查要求变量使用volatile声明。可以和Once的实现代码对照 > > > > > > > @PureWhiteWu > > > 鸟哥求教一下,为什么第四题是C呢? @smallnest
你的理解是对的,通过对第13行,第19行使用atomic,可以给它们之间建立一个happen before的关系,保证写对读可见,否则也可以把第13行放在Lock的临界区中,但是性能就不保证了。 Go的内存模型就是定义happen before,保证某一个时刻的w,确保r能读取到。 > @PureWhiteWu > 我认为在这里问题并不是happens before,而是缓存一致性。 > Lock可以保证拿到锁的goroutine的write一定happens before 其它goroutine的19行的read。 > 但是由于其它goroutine在13行有读过done,所以可能会存在cpu的缓存中,导致19行中read是从CPU缓存读取的,就会导致脏读。 > > > @smallnest > > IA64情况下也是有问题的,因为Lock并没有保护着第13行的读,所以即使本goroutine设置了`done =1`,其它的goroutine在这个时候还是可能读取到`done == 0`,所以必须通过atomic保证happen before关系(atomic基本可以认为保证happen before,虽然官方没有明确保证,但是认为目前使用起来还没遇到过问题) > > >...