zoukankan      html  css  js  c++  java
  • 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,甚至都不需要实现任何方法。他们只是用来加强并发相关的不可变性的。

  • 相关阅读:
    Android工具
    Android工具-DDMS
    Android ADB
    Windows FILETIME 与UNIX时间的转换
    <转>git,github在windows上的搭建
    国内的 Faas 云服务 -- Serverless 收集
    APICloud终于承认侵权并向DCloud道歉了(2019-11-26),知识产权!
    微信及钉钉等小程序开发的可视化工具
    C#的建造者设计模式(Builder),及Aspnet Core的源代码
    AspNet Core 3 的通用主机学习
  • 原文地址:https://www.cnblogs.com/johnnyzhao/p/15376487.html
Copyright © 2011-2022 走看看