lazy_static!
要不就是静态对象引用,要不就得包个Mutex
,包了Mutex
后则必须lock().unwrap()
才能使用,对于串行单线程的程序有没有更方便的方法去使用可变的全局变量呢?其他语言就算是单线程同步代码,全局变量加锁再操作也是有很大性能影响的,所以不知道rust里这个锁会不会有啥性能影响,但无论是各类中英文教程还是StackOverflow的讨论,好像都只提到了上述这一种单例方法,最多是多线程的时候再用Arc
包一下。
1
共 10 条评论, 1 页
评论区
写评论有一说一,Linux上OnceCell配个锁,性能损耗基本上可以忽略不记,Linux上的futex实现的Mutex会自旋一段时间,要是你真没并行是可以立刻获取到锁的 不用任何系统调用。
除此之外要是你真能保证正确使用就直接static mut,然后unsafe,不会有任何性能消耗,和c的全局变量一样。
单线程下,我觉得完全可以unsafe去用可变静态变量
thread_local 的策略是每个线程各自创建一个同名变量,如果多线程的话,数据是不好线程间共享的。 这种玩法仅限于多线程间不需要共享数据的场景。
--
👇
lithbitren: 谢谢分享,果然可以用,性能直逼原生数组,如果给原生数组带套
Refcell
的话,差距基本忽略不计了。不过不是很熟这个宏,api文档还没细看,试了下得用
clone
才能把对象取出来,感觉方法不太对路。--
👇
fakeshadow: thread_local!
学习了,其实只是想找到简洁易上手且不太影响性能的全局变量方法,就像其他语言那样,其实下面推荐的thread_local相对来说已经够好用了。
--
👇
aariety: 你如果只是想要一个现成的 crate,可以另找一个库,就像下面推荐的那样。
不过你的标题问的是怎么实现;如果你想自己实现的话,参考一下 laze_static! 这个宏的源码就可以了,基本原理很容易理解,就是懒加载:
非关键内容都省去了,总之原理就是这么个原理。
你还可以看看标准库里的 std::lazy 这个模块。特别是
Lazy
和SyncLazy
。这两个东西就是标准库里可以实现同样目的的结构体,线程安全和不安全都有。遗憾的是,它们现在还只能在 nightly 版本里使用。你如果只是想要一个现成的 crate,可以另找一个库,就像下面推荐的那样。
不过你的标题问的是怎么实现;如果你想自己实现的话,参考一下 laze_static! 这个宏的源码就可以了,基本原理很容易理解,就是懒加载:
非关键内容都省去了,总之原理就是这么个原理。
你还可以看看标准库里的 std::lazy 这个模块。特别是
Lazy
和SyncLazy
。这两个东西就是标准库里可以实现同样目的的结构体,线程安全和不安全都有。遗憾的是,它们现在还只能在 nightly 版本里使用。如果用unsafe可以实现不带套的全局变量吗?
谢谢分享,果然可以用,性能直逼原生数组,如果给原生数组带套
Refcell
的话,差距基本忽略不计了。不过不是很熟这个宏,api文档还没细看,试了下得用
clone
才能把对象取出来,感觉方法不太对路。--
👇
fakeshadow: thread_local!
thread_local!
嗯?
lazy_static!
不是要求要实现Sync
才能用吗,求大佬明示。--
👇
gwy15:
Rc<RefCell<>>
Rc<RefCell<>>