1
bruce0 2022-11-06 19:02:55 +08:00
并发安全, 要么加锁,要么 channel 吧, sync.map 适合读多写少的场景, 写多读少, 用 rwlook 呢, 再加个 分片, 对 key 取值, 分散到不同的 key 中, 减小锁的粒度
|
2
fds 2022-11-06 20:11:10 +08:00
你确定你写的 slice 是并发安全的么?我看这里的讨论
https://groups.google.com/g/golang-nuts/c/cQdZJMQSxTE/m/K_IrQfoZBQAJ - any global variables. Even reading an 'int' while some other goroutine is updating it is unsafe; it may give undefined behavior. 在你用新 arrays 覆盖旧 arrays 的瞬间,有没有可能别的 goroutine 读到一个错误的地址呢? 你说的应用场景我觉得 buffered channel 就可以吧,比如设置大小为 1000 ,有 10 个 worker 从里面读请求。如果要退出,可以另外启动一个 goroutine 从里面把剩下的 log 下来。 |
4
wencan OP @fds
根据你的描述,我找到了 Slice 的 Append 方法 https://github.com/wencan/gox/blob/main/xsync/slice.go#L183 Append 下面的 Grow 段是加锁的 覆盖是通过 sync.Value 操作的 因此不存在你说的情况 不知道我有没有理解错你的意思 |
5
lysS 2022-11-06 20:58:10 +08:00
|
9
fds 2022-11-07 10:22:47 +08:00
@wencan 哦,对,是我没看到下面 Slice 的具体实现,只看了最上面的 comment 就下结论了,太草率。
不过我觉得这样套很多 atomic 只是单元素的读性能会好,如果批量读写大量数据就不好说了,应用场景比较特殊。一般用 go 写的应用,只要锁的粒度不太大,应该不会成为瓶颈吧?网络请求、磁盘 IO 的时间比这都大多了。 |
10
yuancoder 2022-11-07 11:34:13 +08:00
既然是写多读少,每个协程都使用自己的 slice , 读的时候再加锁
|
12
lysS 2022-11-07 12:39:25 +08:00
就实现来说,数组需要 delete 本身就是不太合理的,你可能需要 link/heap/map? 并发安全而言,就直接加锁吧,锁和原子变量性能上其实没多大差别; free-lock 其实比较鸡肋
|