深入浅出Rust(第四部分)


传送门:
深入浅出Rust(第一部分-1)
深入浅出Rust(第一部分-2)
深入浅出Rust(第二部分-1)
深入浅出Rust(第二部分-2)
深入浅出Rust(第三部分-1)
深入浅出Rust(第三部分-2)
深入浅出Rust(第四部分)
深入浅出Rust(第五部分)


第四部分 - 线程安全

Rust在编译器层面做了很多工作,进而在编译过程就发现和阻止线程不安全的情形

第27章 线程安全

1. 什么是线程

2. 启动线程

thread::spawn(MOVE ||{
    //线程内部逻辑
});

相当于做了闭包代码块

Thead模块常用API:

  • thread::sleep(dur: Duration)
  • thread::yield_now()
  • thread::current()
  • thread::park()
  • thread::Thread::unpark(&self)

3. 避免数据竞争

直接传mut变量,copy类型进去,都会造成编译错误.

4. send & Sync

Rust正是通过这两个特殊的trait,对线程安全进行了控制

pub fn spawn<F,T>(f: F) -> JoinHandle<T>
    where F: FnOne() -> T, F:Send + 'static, T: Send +'static

从spawn的函数签名可以参数,F和T需要满足Send trait,因此在线程间传递所有权会发生安全问题的类型,Rust就能检测出来.

第28章 详解Send和Sync

1. 什么是Send

  • Send trait满足不同线程间传递所有权是安全的
  • 包括基本类型,内部不含引用的类型(string),泛型参数满足的(Cell<T>,RefCell<T>,Mutex<T>)
  • 不包括RC<T>

2. 什么是Sync

  • Sync trait满足不同线程使用&T访问同一变量
  • 包括基本类型,泛型参数满足的(Box<T>,Vec<T>,Mutex<T>)
  • 不包括Cell<T>,RefCell<T>

3. 自动推理

  • 实际上 Send和Sync都是std::marker模块的特殊trait,用户不用手写impl,而是编译器自动完成
  • 如果要自己写,一定要配合unsafe关键字,并且自己保证其安全性

第29章 状态共享

1. ARC

  • Arc是Rc的线程安全版本
29-1.png

2. Mutex(重点)

  • Mutex提供安全的内部可变性(通过lock()调用)
  • lock()方法返回LockResult类型,
type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;

如果lock过程发生了panic,那么这个Mutex则变为"有毒"状态.

3. RwLock

  • RwLock和使用类似Mutex,相对来说,更不严格一点,可以通过read实现共享,write实现独占.

4. Atomic

  • Atomic系列类型提供了"原子操作",因此他们都是符合Sync的,可以在多线程间共享使用.
  • 修改时要用fetch_add()和fetch_sub()实现原子化的数据增减,而load,store本身虽然原子化,但是无法保证两个操作之间的原子化.

5. 死锁

  • rust并不保证线程间不出现死锁,这个需要程序员自行完善逻辑

6. Barrier

  • Barrier类似waitgroup,当条件完全满足才能继续

7. Condvar(重点)

  • Condvar通常与Mutex配套使用,用来在线程之前进行消息传递,从而进行手工同步
29-2.png

8. 全局变量

  • 全局变量显然不适合用在多线程里,太容易造成线程不安全了.
  • mut全局变量基本无法满足Send,Sync约束
  • 可以用atomic型全局变量(限定为简单的i32)

9. 线程局部存储

  • threalocal!{}宏声明,××.with{}限定使用范围.
  • java也一样这么搞的

第30章 管道

显然,Rust的channel比起Go,还是有差距的.

1. 异步管道

  • 异步管道(std::sync::mpsc::channel),实现管道的异步读写(不需要考虑管道本身大小)
  • Send和Receiver都必须满足T: Send约束.
  • 可以实现多发单收

2. 同步管道

  • 异步管道(std::sync::mpsc::sync_channel),实现管道的同步读写(管道大小为1)

第31章 第三方并行开发库

1. threadpool

  • new出大小,execute执行

2. scoped-threadpool

  • 线程内部直接使用&mut访问父线程变量,而不需用Arc包装

3. parking_lot

  • 实现另外一套同步原语(Mutex,CondVar)

4. crossbeam

  • 实现了双端管道

5. rayon

31-1.png
  • 实现了并行迭代器和join()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容