W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
ch16-04-extensible-concurrency-sync-and-send.md
commit a7a6804a2444ee05ff8b93f54973a9ce0f6511c1
Rust 的并發(fā)模型中一個(gè)有趣的方面是:語言本身對(duì)并發(fā)知之 甚少。我們之前討論的幾乎所有內(nèi)容,都屬于標(biāo)準(zhǔn)庫,而不是語言本身的內(nèi)容。由于不需要語言提供并發(fā)相關(guān)的基礎(chǔ)設(shè)施,并發(fā)方案不受標(biāo)準(zhǔn)庫或語言所限:我們可以編寫自己的或使用別人編寫的并發(fā)功能。
然而有兩個(gè)并發(fā)概念是內(nèi)嵌于語言中的:std::marker
中的 Sync
和 Send
trait。
Send
標(biāo)記 trait 表明實(shí)現(xiàn)了 Send
的類型值的所有權(quán)可以在線程間傳送。幾乎所有的 Rust 類型都是Send
的,不過有一些例外,包括 Rc<T>
:這是不能 Send
的,因?yàn)槿绻寺×?nbsp;Rc<T>
的值并嘗試將克隆的所有權(quán)轉(zhuǎn)移到另一個(gè)線程,這兩個(gè)線程都可能同時(shí)更新引用計(jì)數(shù)。為此,Rc<T>
被實(shí)現(xiàn)為用于單線程場(chǎng)景,這時(shí)不需要為擁有線程安全的引用計(jì)數(shù)而付出性能代價(jià)。
因此,Rust 類型系統(tǒng)和 trait bound 確保永遠(yuǎn)也不會(huì)意外的將不安全的 Rc<T>
在線程間發(fā)送。當(dāng)嘗試在示例 16-14 中這么做的時(shí)候,會(huì)得到錯(cuò)誤 the trait Send is not implemented for Rc<Mutex<i32>>
。而使用標(biāo)記為 Send
的 Arc<T>
時(shí),就沒有問題了。
任何完全由 Send
的類型組成的類型也會(huì)自動(dòng)被標(biāo)記為 Send
。幾乎所有基本類型都是 Send
的,除了第十九章將會(huì)討論的裸指針(raw pointer)。
Sync
標(biāo)記 trait 表明一個(gè)實(shí)現(xiàn)了 Sync
的類型可以安全的在多個(gè)線程中擁有其值的引用。換一種方式來說,對(duì)于任意類型 T
,如果 &T
(T
的不可變引用)是 Send
的話 T
就是 Sync
的,這意味著其引用就可以安全的發(fā)送到另一個(gè)線程。類似于 Send
的情況,基本類型是 Sync
的,完全由 Sync
的類型組成的類型也是 Sync
的。
智能指針 Rc<T>
也不是 Sync
的,出于其不是 Send
相同的原因。RefCell<T>
(第十五章討論過)和 Cell<T>
系列類型不是 Sync
的。RefCell<T>
在運(yùn)行時(shí)所進(jìn)行的借用檢查也不是線程安全的。Mutex<T>
是 Sync
的,正如 “在線程間共享 Mutex<T>
通常并不需要手動(dòng)實(shí)現(xiàn) Send
和 Sync
trait,因?yàn)橛?nbsp;Send
和 Sync
的類型組成的類型,自動(dòng)就是 Send
和 Sync
的。因?yàn)樗麄兪菢?biāo)記 trait,甚至都不需要實(shí)現(xiàn)任何方法。他們只是用來加強(qiáng)并發(fā)相關(guān)的不可變性的。
手動(dòng)實(shí)現(xiàn)這些標(biāo)記 trait 涉及到編寫不安全的 Rust 代碼,第十九章將會(huì)講述具體的方法;當(dāng)前重要的是,在創(chuàng)建新的由不是 Send
和 Sync
的部分構(gòu)成的并發(fā)類型時(shí)需要多加小心,以確保維持其安全保證。“The Rustonomicon” 中有更多關(guān)于這些保證以及如何維持他們的信息。
這不會(huì)是本書最后一個(gè)出現(xiàn)并發(fā)的章節(jié):第二十章的項(xiàng)目會(huì)在更現(xiàn)實(shí)的場(chǎng)景中使用這些概念,而不像本章中討論的這些小例子。
正如之前提到的,因?yàn)?Rust 本身很少有處理并發(fā)的部分內(nèi)容,有很多的并發(fā)方案都由 crate 實(shí)現(xiàn)。他們比標(biāo)準(zhǔn)庫要發(fā)展的更快;請(qǐng)?jiān)诰W(wǎng)上搜索當(dāng)前最新的用于多線程場(chǎng)景的 crate。
Rust 提供了用于消息傳遞的信道,和像 Mutex<T>
和 Arc<T>
這樣可以安全的用于并發(fā)上下文的智能指針。類型系統(tǒng)和借用檢查器會(huì)確保這些場(chǎng)景中的代碼,不會(huì)出現(xiàn)數(shù)據(jù)競爭和無效的引用。一旦代碼可以編譯了,我們就可以堅(jiān)信這些代碼可以正確的運(yùn)行于多線程環(huán)境,而不會(huì)出現(xiàn)其他語言中經(jīng)常出現(xiàn)的那些難以追蹤的 bug。并發(fā)編程不再是什么可怕的概念:無所畏懼地并發(fā)吧!
接下來,讓我們討論一下當(dāng) Rust 程序變得更大時(shí),有哪些符合語言習(xí)慣的問題建模方法和結(jié)構(gòu)化解決方案,以及 Rust 的風(fēng)格是如何與面向?qū)ο缶幊蹋∣bject Oriented Programming)中那些你所熟悉的概念相聯(lián)系的。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: