0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

重点讲解Send与Sync相关的并发知识

jf_wN0SrCdH 来源:光城 2023-01-16 09:54 次阅读

Rust那些事之并发Send与Sync

Send与Sync在Rust中属于marker trait,代码位于marker.rs,在标记模块中还有Copy、Unpin等trait。

在marker.rs中是通过auto trait来实现。

pubunsafeautotraitSync{}

auto trait又称为opt-in, built-in trait (OIBIT)。这是一种不稳定的特性,每个类型都会自动实现一个特征,除非它们选择退出或包含一个不实现该特征的类型。

换言之,opt-in对应还有个opt-out,可以通过!(negative trait impl)语法来实现。

例如:下面代码中第一行表示类型Wrapper实现了Send,但是却没实现Sync。

unsafeimplSendforWrapper{}
unsafeimpl!SyncforWrapper{}

本节将会重点讲解Send、Sync相关的并发知识。

1.auto trait

可以通过安装nightly版使用feature特性。

rustuptoolchaininstallnightly

下面以自定义auto trait实现为例:

#![feature(negative_impls)]
#![feature(auto_traits)]
autotraitIsCool{}

impl!IsCoolforString{}

structMyStruct;
structHasAString(String);

fncheck_cool(_:C){}

调用:

check_cool(42);
check_cool(false);
check_cool(MyStruct);
#thetrait`IsCool`isnotimplementedfor`std::String`
check_cool(String::new());

这里给了一个简单的例子,展示了auto trait的用法,当没有实现(通过!)auto trait时,编译器会在编译阶段报:the trait XXX is not implemented for YYY。

2.Send与Sync

Send含义:跨线程move,ownership。Sync含义:跨线程share data,borrow。

通常在我们编译多线程代码时,会存在所有权转移、数据共享。那么问题来了,Rc与原生指针是否可以在多线程使用呢?

我们打开Rc(Reference Counting, 引用计数)的源码可以看到这里使用了negative trait,并没有实现Send与Sync,因此通过Rc包裹的对象并不是线程安全的,只能用在单线程中。

impl!marker::SendforRc{}
impl!marker::SyncforRc{}

如果我们将它用在多线程中,会出什么问题呢?

fnmain(){
letval=std::new(5);
lett=std::spawn(move||{
println!("thisisathreadval:{}",val);
});

t.join().unwrap();
}

报错:

error[E0277]:`Rc`cannotbesentbetweenthreadssafely
...
thetrait`Send`isnotimplementedfor`Rc`
...

与之对应,Arc(Atomic Reference Counted, 原子引用计数),可以看一下源码实现:

unsafeimplSendforArc{}
unsafeimplSyncforArc{}

Send与Sync都实现了。

Send可以实现在多线程间安全传递所有权,Sync可以线程安全的共享数据(例如:引用)。

此外,官方文档:当且仅当类型T的引用&T是Send,T是Sync。

大概意思就是如果引用都无法在多线程之前传递,那么底层数据变无法进行数据共享了。

marker.rs中还有段比较重要的代码,表示原生指针不是线程安全的,没有实现Send、Sync trait。

impl!Sendfor*constT{}
impl!Sendfor*mutT{}
impl!Syncfor*constT{}
impl!Syncfor*mutT{}

Mutex与RwLock

Mutex与RwLock相比于其他语言来说,实现了用户友好的接口,通过new即可将类型传递进去。

Arc::new(Foo{}))

在Go中使用Mutex,张这个样子:

vmap[string]int
muxsync.Mutex

可以看到rust一行便可以知道保护的是哪个数据。Mutex是用来保护共享变量,所以这个变量类型T我们猜测可以是安全的,也可以是不安全的,所以Sync是不被要求的,因此我们看源码:

unsafeimplSendforMutex{}
unsafeimplSyncforMutex{}

Mutex会去实现Send与Sync,要求的类型T一定是具有所有权(实现Send),但是并不要求数据是否是安全的(没实现Sync)。

同理:RwLock是读写锁,需要满足并发读,因此要求T必须实现Sync。

unsafeimplSendforRwLock{}
unsafeimplSyncforRwLock{}

小知识

前面讲解了raw pointer并不是线程安全的,那么如何实现线程安全呢?

其实也比较简单:可以通过如下多种方法:

自定义类型

将raw pointer包裹起来即可。

structWrapper(*muti32);
unsafeimplSendforWrapper{}
unsafeimplSyncforWrapper{}

Box

使用智能指针Box。

Box::new(my_num)






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARC
    ARC
    +关注

    关注

    0

    文章

    36

    浏览量

    16353
  • rust语言
    +关注

    关注

    0

    文章

    58

    浏览量

    2958

原文标题:Rust那些事之并发Send与Sync

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    《自动控制原理》课程重点知识

    《自动控制原理》课程重点知识,大学期末考试复习必备资料。
    发表于 01-22 11:13

    2019年中级通信工程师考试重点知识讲解

    通信工程师最新大纲定制课程,根据教材每个章节讲解资料,让你在快速掌握新大纲的重点考点。帮助你通过考试。适合人群:期望在最短的时间内通过中级通信工程师考试的行业从业人员;通信工程师备考人员
    发表于 08-16 12:03

    蓝牙模块基础知识讲解 精选资料分享

    随着蓝牙技术的不断更新发展,蓝牙的传输速率也在不断的提高,并且功耗也是越来越低,这也使得蓝牙的应用范围变得更加广泛。但是若是想自己设计一套完善的蓝牙系统,就必须充分的掌握蓝牙的相关技术知识,如:射频
    发表于 07-27 06:20

    Systick定时器基础知识讲解

    Systick定时器基础知识讲解Systick相关寄存器库函数讲解delay延时函数讲解(Systick应用)(借鉴正点原子网课)(一)Sy
    发表于 08-19 07:18

    详细介绍了Java泛型、注解、并发编程

    介绍了Java泛型、注解、并发编程、数据传输与序列化、高效IO、容器集合、反射与类加载以及JVM重点知识线程、内存模型、JVM运行时内存、垃圾回收与算法、Java中四种引用类型、GC 分代收集算法
    发表于 08-20 06:09

    详细讲解C++串口的相关知识

    笔者的开发板是正点原子的stm32F103zet6迷你板。串口的使用是USART1.单片机相关串口的程序就不讲解,编写上位机程序是使用C++语言,在VS2017里面编写,下面进入正题。一、相关
    发表于 08-24 06:56

    LPUART_RTOS_Send() 停止FreeRTOS SwTimer周期,如何修复它并发送UART消息1秒?

    SwTimerCallback()中添加LPUART_RTOS_Send()停止SwTimer 1秒周期回调,注释LPUART_RTOS_Send()SwTimer周期正常。我附上了修改后的 freertos_lpuart.c。 如何修复它
    发表于 03-24 08:34

    高频放大电路知识讲解

    高频放大电路知识讲解
    发表于 05-25 21:57 896次下载

    手机硬件知识讲解【PDF】

    手机硬件知识讲解
    发表于 01-17 19:47 108次下载

    Java设计知识讲解

    本文档内容介绍了基于Java设计知识讲解,供参考
    发表于 03-26 11:09 16次下载

    fmax相关知识讲解资料下载

    电子发烧友网为你提供fmax相关知识讲解资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子
    发表于 03-30 08:40 10次下载
    fmax<b class='flag-5'>相关</b><b class='flag-5'>知识</b><b class='flag-5'>讲解</b>资料下载

    C语言基础知识讲解

    C语言基础知识讲解
    发表于 05-19 17:39 13次下载

    EMC的原理基础知识讲解

    EMC的原理基础知识讲解免费下载。
    发表于 05-28 16:54 41次下载

    华为防雷接地基础知识讲解

    华为防雷接地基础知识讲解
    发表于 06-03 10:24 22次下载

    SPI协议知识讲解

    电子发烧友网站提供《SPI协议知识讲解.ppt》资料免费下载
    发表于 11-16 10:41 2次下载
    SPI协议<b class='flag-5'>知识</b><b class='flag-5'>讲解</b>