• Rust-线程:使用Sync和Send trait的可扩展并发


    Rust的并发模型中一个有趣的方面是:语言本身对并发知之甚少。我们之前讨论的几乎所有内容,都属于标准库,而不是语言本身的内容。由于不需要语言提供并发相关的基础设施,并发方案不受标准库或语言所限:我们可以编写自已的或使用别人编写的并发功能。

    然而有两个并发概念是内嵌于语言中的:std::marker 中的 SyncSend trait。

    通过Send允许在线程间转移所有权

    Send标记trait表明类型的所有权可以在线程间传递。几乎所有的Rust类型都是Send的,不过有一些例外,包括Rc<T>: 这是不能Send的,因为如果克隆了Rc<T>的值并尝试将克隆的所有权转移到另一个线程,这两个线程都可能同时更新引用计数。为此,Rc<T>被实现为用于单线程场景,这时不需要为拥有线程安全的引用计数而付出性能代价。

    因此,Rust类型系统和trait bound确保永远也不会意外的将不安全的Rc<T>在线程间发送。

    任何完全由Send的类型组成的类型也会自动被标记为Send。几乎所有基本类型都是Send的,除了裸指针(raw pointer)。

    Sync允许多线程访问

    Sync标记trait表明一个实现了Sync的类型可以安全的在多个线程中拥有其值的引用。换一种方式来说,对于任意类型T,如果 &T (T的引用)是Send的话T就是Sync的,这意味着其引用就可以安全的发送到另一个线程。类似于Send的情况,基本类型是Sync的,完全由Sync的类型组成的类型也是Sync的。

    智能指针Rc<T>也不是Sync的,出于其不是Send相同的原因。RefCell<T>和Cell<T>系列类型不是Sync的。RefCell<T>在运行时所进行的借用检查也不是线程安全的。Mutex<T>是Sync的,正如"在线程间共享Mutex<T>"部分所讲的它可以被用来在多线程中共享访问。

    手动实现Send和Sync是不安全的

    通常并不需要手动实现SendSync trait,因为由Send和Sync的类型组成的类型,自动就是Send和Sync的。因为他们是标记trait,甚至都不需要实现任何方法。他们只是用来加强并发相关的不可变性的。

  • 相关阅读:
    Jquery里live事件移除原因
    js委托事件-addEventListeners(冒泡方向)
    后端同同不肯给我算好的时间差给我,只好自己写了:
    js滚动到顶部底部代码
    浏览器地址栏运行HTML代码(谷歌)
    黑马vue---56-58、vue组件创建的三种方式
    黑马vue---46、vue使用过渡类名实现动画
    黑马vue---28、vue中全局过滤器的基本使用
    vue devtools无法使用
    红心点赞效果的实现
  • 原文地址:https://www.cnblogs.com/johnnyzhao/p/15376487.html
Copyright © 2020-2023  润新知