当前用的是Arc<Mutex>,场景主要用两个: 1.大量线程(20+)只读取变量,没有任何写入,性能要求较高。希望能不加锁读取,可以读取老的值。 2.少量线程(2-4)会对变量进行读写,无性能要求。
目前针对场景二是,直接加锁实现读写,应该没问题。 针对场景1的话,使用的代码老是出错:请问我该用Arc来做多线程读写吗?
1
共 13 条评论, 1 页
当前用的是Arc<Mutex>,场景主要用两个: 1.大量线程(20+)只读取变量,没有任何写入,性能要求较高。希望能不加锁读取,可以读取老的值。 2.少量线程(2-4)会对变量进行读写,无性能要求。
目前针对场景二是,直接加锁实现读写,应该没问题。 针对场景1的话,使用的代码老是出错:请问我该用Arc来做多线程读写吗?
评论区
写评论个人写的自旋锁性能很难超过Mutex
--
👇
Bai-Jinlin: 要不换成自旋锁试试?
要不换成自旋锁试试?
如果值是i8应该不会有问题 但何必自己给自己挖坑 拆分拆分 搞几个原子锁代替不香么
👇
ThalliMega: 基本上肯定会触发data race 不知道会不会有其他的ub
--
👇
Pikachu: 这个真的不会触发什么UB吗?
--
👇
ThalliMega: 如果RwLock的性能不够,应该要考虑unsafe了?
一种可供参考的轻量级读写锁的的写法,把数据和锁分离,读操作是无锁的,不过可靠性没有Rwlock高,理论上读还是有可能在高并发下出现非预期结果。
要保证可靠性,要不然就用
Rwlock
,要不然就用第三方库arc_swap
,arc-swap有点像原子操作,load方法下读性能很高,应该是lockfree的,不过store方法下的写操作性能一般,因为只能整体替换,无法类似写锁那样可变引用后局部修改。Arc<RwLock<_>>
中其实主要性能消耗还是在RwLock
,Arc
本身对性能的消耗其实很小,而且其本身有一定特殊性,甚至在某些场景包上Arc
比不包还要快。基本上肯定会触发data race 不知道会不会有其他的ub
--
👇
Pikachu: 这个真的不会触发什么UB吗?
--
👇
ThalliMega: 如果RwLock的性能不够,应该要考虑unsafe了?
这个真的不会触发什么UB吗?
--
👇
ThalliMega: 如果RwLock的性能不够,应该要考虑unsafe了?
core 欢迎你
--
👇
ThalliMega: 如果RwLock的性能不够,应该要考虑unsafe了?
如果RwLock的性能不够,应该要考虑unsafe了?
我有一个非常暴力的办法:开20多个mpsc queue,每个consumer对应一个。queue的capacity设成1,如果出现overflow的话把最旧的数据丢弃掉。
每次consumer维护一个thread local。读取数据的时候,先尝试把queue里最新的读出来,同时更新thread local。如果queue是空的,那就直接返回thread local。
缺点是producer要往20多个channel里面写数据……但是既然你已经说了producer端的性能不重要,那应该可以接受?
(不太清楚这叫什么pattern,可能有个比较正式的名字吧?)
是对场景1中有性能影响
--
👇
lsk569937453: 只用Mutex的话,每次读写数据也必须加lock,这样对我的场景2中有性能影响。能不能读数据的时候不加lock?
只用Mutex的话,每次读写数据也必须加lock,这样对我的场景2中有性能影响。能不能读数据的时候不加lock?
你这根本都不是Arc的问题。全局变量用不上Arc。
RwLock<T>
就行, 全局变量没必要包Arc
了