欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

rust使用Atomic創(chuàng)建全局變量和使用操作方法

 更新時(shí)間:2024年05月05日 11:24:09   作者:1024小神  
從 Rust1.34 版本后,就正式支持原子類型,原子指的是一系列不可被 CPU 上下文交換的機(jī)器指令,這些指令組合在一起就形成了原子操作,這篇文章主要介紹了rust使用Atomic創(chuàng)建全局變量和使用,需要的朋友可以參考下

Mutex用起來簡(jiǎn)單,但是無法并發(fā)讀,RwLock可以并發(fā)讀,但是使用場(chǎng)景較為受限且性能不夠,那么有沒有一種全能性選手呢? 歡迎我們的Atomic閃亮登場(chǎng)。

從 Rust1.34 版本后,就正式支持原子類型。原子指的是一系列不可被 CPU 上下文交換的機(jī)器指令,這些指令組合在一起就形成了原子操作。在多核 CPU 下,當(dāng)某個(gè) CPU 核心開始運(yùn)行原子操作時(shí),會(huì)先暫停其它 CPU 內(nèi)核對(duì)內(nèi)存的操作,以保證原子操作不會(huì)被其它 CPU 內(nèi)核所干擾。

由于原子操作是通過指令提供的支持,因此它的性能相比鎖和消息傳遞會(huì)好很多。相比較于鎖而言,原子類型不需要開發(fā)者處理加鎖和釋放鎖的問題,同時(shí)支持修改,讀取等操作,還具備較高的并發(fā)性能,幾乎所有的語言都支持原子類型。

可以看出原子類型是無鎖類型,但是無鎖不代表無需等待,因?yàn)樵宇愋蛢?nèi)部使用了CAS循環(huán),當(dāng)大量的沖突發(fā)生時(shí),該等待還是得等待!但是總歸比鎖要好。

CAS 全稱是 Compare and swap, 它通過一條指令讀取指定的內(nèi)存地址,然后判斷其中的值是否等于給定的前置值,如果相等,則將其修改為新的值

原子類型的一個(gè)常用場(chǎng)景,就是作為全局變量來使用:

use std::sync::atomic::{AtomicI32, Ordering};
use std::thread::{self, JoinHandle};
static R: AtomicI32 = AtomicI32::new(0);
fn thread_add() {
    // 多個(gè)線程修改全局變量
    for i in 0..1000 {
        R.fetch_add(1, Ordering::Relaxed);
    }
}
fn main() {
    // This will POST a body of `foo=bar&baz=quux`
    let mut init_data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let mut hand_list = Vec::with_capacity(init_data.len());
    for i in init_data {
        hand_list.push(thread::spawn(thread_add));
    }
    for h in hand_list {
        h.join().unwrap();
    }
    let r_value = R.load(Ordering::Relaxed);
    println!("全局變量最后的值是: {r_value:?}");
}

并且能夠保證數(shù)據(jù)讀寫不出錯(cuò):

以上代碼啟動(dòng)了數(shù)個(gè)線程,每個(gè)線程都在瘋狂對(duì)全局變量進(jìn)行加 1 操作, 最后將它與線程數(shù) * 加1次數(shù)進(jìn)行比較,如果發(fā)生了因?yàn)槎鄠€(gè)線程同時(shí)修改導(dǎo)致了臟數(shù)據(jù),那么這兩個(gè)必將不相等。好在,它沒有讓我們失望,不僅快速的完成了任務(wù),而且保證了 100%的并發(fā)安全性。

當(dāng)然以上代碼的功能其實(shí)也可以通過Mutex來實(shí)現(xiàn),但是后者的強(qiáng)大功能是建立在額外的性能損耗基礎(chǔ)上的,因此性能會(huì)遜色不少:

Atomic實(shí)現(xiàn):673ms Mutex實(shí)現(xiàn): 1136ms

可以看到Atomic實(shí)現(xiàn)會(huì)比Mutex41%,實(shí)際上在復(fù)雜場(chǎng)景下還能更快(甚至達(dá)到 4 倍的性能差距)!

還有一點(diǎn)值得注意: 和Mutex一樣,Atomic的值具有內(nèi)部可變性,你無需將其聲明為mut

use std::sync::Mutex;
use std::sync::atomic::{Ordering, AtomicU64};
struct Counter {
    count: u64
}
fn main() {
    let n = Mutex::new(Counter {
        count: 0
    });
    n.lock().unwrap().count += 1;
    let n = AtomicU64::new(0);
    n.fetch_add(0, Ordering::Relaxed);
}

這里有一個(gè)奇怪的枚舉成員Ordering::Relaxed, 看上去很像是排序作用,但是我們并沒有做排序操作啊?實(shí)際上它用于控制原子操作使用的內(nèi)存順序

內(nèi)存順序

內(nèi)存順序是指 CPU 在訪問內(nèi)存時(shí)的順序,該順序可能受以下因素的影響:

代碼中的先后順序

編譯器優(yōu)化導(dǎo)致在編譯階段發(fā)生改變(內(nèi)存重排序 reordering)
運(yùn)行階段因 CPU 的緩存機(jī)制導(dǎo)致順序被打亂

限定內(nèi)存順序的 5 個(gè)規(guī)則:

在理解了內(nèi)存順序可能存在的改變后,你就可以明白為什么 Rust 提供了Ordering::Relaxed用于限定內(nèi)存順序了,事實(shí)上,該枚舉有 5 個(gè)成員:

Relaxed, 這是最寬松的規(guī)則,它對(duì)編譯器和 CPU 不做任何限制,可以亂序。
Release 釋放,設(shè)定內(nèi)存屏障(Memory barrier),保證它之前的操作永遠(yuǎn)在它之前,但是它后面的操作可能被重排到它前面。
Acquire 獲取, 設(shè)定內(nèi)存屏障,保證在它之后的訪問永遠(yuǎn)在它之后,但是它之前的操作卻有可能被重排到它后面,往往和Release在不同線程中聯(lián)合使用。
AcqRel, 是 Acquire 和 Release 的結(jié)合,同時(shí)擁有它們倆提供的保證。比如你要對(duì)一個(gè) atomic 自增 1,同時(shí)希望該操作之前和之后的讀取或?qū)懭氩僮鞑粫?huì)被重新排序。
SeqCst 順序一致性, SeqCst就像是AcqRel的加強(qiáng)版,它不管原子操作是屬于讀取還是寫入的操作,只要某個(gè)線程有用到SeqCst的原子操作,線程中該SeqCst操作前的數(shù)據(jù)操作絕對(duì)不會(huì)被重新排在該SeqCst操作之后,且該SeqCst操作后的數(shù)據(jù)操作也絕對(duì)不會(huì)被重新排在SeqCst操作前。
這些規(guī)則由于是系統(tǒng)提供的,因此其它語言提供的相應(yīng)規(guī)則也大同小異,大家如果不明白可以看看其它語言的相關(guān)解釋。

Atomic 能替代鎖嗎

那么原子類型既然這么全能,它可以替代鎖嗎?答案是不行:

對(duì)于復(fù)雜的場(chǎng)景下,鎖的使用簡(jiǎn)單粗暴,不容易有坑
std::sync::atomic包中僅提供了數(shù)值類型的原子操作:AtomicBool, AtomicIsize, AtomicUsize, AtomicI8, AtomicU16等,而鎖可以應(yīng)用于各種類型
在有些情況下,必須使用鎖來配合,例如上一章節(jié)中使用Mutex配合Condvar

Atomic 的應(yīng)用場(chǎng)景

事實(shí)上,Atomic雖然對(duì)于用戶不太常用,但是對(duì)于高性能庫的開發(fā)者、標(biāo)準(zhǔn)庫開發(fā)者都非常常用,它是并發(fā)原語的基石,除此之外,還有一些場(chǎng)景適用:

無鎖(lock free)數(shù)據(jù)結(jié)構(gòu)
全局變量,例如全局自增 ID, 在后續(xù)章節(jié)會(huì)介紹
跨線程計(jì)數(shù)器,例如可以用于統(tǒng)計(jì)指標(biāo)
以上列出的只是Atomic適用的部分場(chǎng)景,具體場(chǎng)景需要大家未來根據(jù)自己的需求進(jìn)行權(quán)衡選擇。

到此這篇關(guān)于rust使用Atomic創(chuàng)建全局變量和使用的文章就介紹到這了,更多相關(guān)rust創(chuàng)建全局變量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Rust中的所有權(quán)機(jī)制

    詳解Rust中的所有權(quán)機(jī)制

    Rust?語言提供了跟其他系統(tǒng)編程語言相同的方式來控制你使用的內(nèi)存,但擁有數(shù)據(jù)所有者在離開作用域后自動(dòng)清除其數(shù)據(jù)的功能意味著你無須額外編寫和調(diào)試相關(guān)的控制代碼,這篇文章主要介紹了Rust中的所有權(quán)機(jī)制,需要的朋友可以參考下
    2022-10-10
  • Rust中實(shí)例化動(dòng)態(tài)對(duì)象的示例詳解

    Rust中實(shí)例化動(dòng)態(tài)對(duì)象的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Rust中實(shí)例化動(dòng)態(tài)對(duì)象的多種方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • Rust中的關(guān)聯(lián)類型總結(jié)

    Rust中的關(guān)聯(lián)類型總結(jié)

    關(guān)聯(lián)類型是定義通用trait的一種機(jī)制。它允許在trait中定義一個(gè)或多個(gè)占位符類型,這些類型將在trait的實(shí)現(xiàn)中具體化。文中有詳細(xì)示例代碼供參考,需要的朋友可以閱讀一下
    2023-05-05
  • Rust語言之Prometheus系統(tǒng)監(jiān)控工具包的使用詳解

    Rust語言之Prometheus系統(tǒng)監(jiān)控工具包的使用詳解

    Prometheus?是一個(gè)開源的系統(tǒng)監(jiān)控和警報(bào)工具包,最初是由SoundCloud構(gòu)建的,隨著時(shí)間的發(fā)展,Prometheus已經(jīng)具有適用于各種使用場(chǎng)景的版本,為了開發(fā)者方便開發(fā),更是有各種語言版本的Prometheus的開發(fā)工具包,本文主要介紹Rust版本的Prometheus開發(fā)工具包
    2023-10-10
  • Rust調(diào)用C程序的實(shí)現(xiàn)步驟

    Rust調(diào)用C程序的實(shí)現(xiàn)步驟

    本文主要介紹了Rust調(diào)用C程序的實(shí)現(xiàn)步驟,包括創(chuàng)建C函數(shù)、編譯C代碼、鏈接Rust和C代碼等步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Rust語言數(shù)據(jù)類型的具體使用

    Rust語言數(shù)據(jù)類型的具體使用

    在Rust中,每個(gè)值都有一個(gè)明確的數(shù)據(jù)類型,本文主要介紹了Rust語言數(shù)據(jù)類型的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • Rust Aya 框架編寫 eBPF 程序

    Rust Aya 框架編寫 eBPF 程序

    這篇文章主要介紹了Rust Aya 框架編寫 eBPF 程序方法的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • 解析Rust?struct?中的生命周期

    解析Rust?struct?中的生命周期

    rust?的生命周期保證了內(nèi)存的安全性,同時(shí)也增加了開發(fā)者的心智負(fù)擔(dān)。是在上線之前多費(fèi)心思寫代碼,還是在上線以后忙忙活活查問題,這是個(gè)?trade?off?問題,這篇文章主要介紹了Rust?struct?中的生命周期,需要的朋友可以參考下
    2022-10-10
  • Rust 累計(jì)時(shí)間長(zhǎng)度的操作方法

    Rust 累計(jì)時(shí)間長(zhǎng)度的操作方法

    在Rust中,如果你想要記錄累計(jì)時(shí)間,通??梢允褂脴?biāo)準(zhǔn)庫中的std::time::Duration類型,這篇文章主要介紹了Rust如何累計(jì)時(shí)間長(zhǎng)度,需要的朋友可以參考下
    2024-05-05
  • Rust中的不安全代碼詳解

    Rust中的不安全代碼詳解

    這篇文章主要為大家介紹了Rust中的不安全代碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04

最新評(píng)論