国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Rust語言之多線程

這篇具有很好參考價值的文章主要介紹了Rust語言之多線程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


一、簡介

多線程 是一種并發(fā)執(zhí)行的技術(shù),它允許一個程序或進程同時執(zhí)行多個線程。每個線程都是程序執(zhí)行的一個獨立路徑,它們可以并行運行,共享進程的資源(如內(nèi)存空間),但每個線程有自己的指令指針、堆棧和局部變量。多線程的主要目的是提高程序的執(zhí)行效率,通過同時執(zhí)行多個任務(wù)來充分利用計算機的多核處理器。

  • 在Rust語言中,多線程編程是通過標(biāo)準(zhǔn)庫中的std::thread模塊來實現(xiàn)的。Rust提供了創(chuàng)建和管理線程的API,以及用于線程間同步和通信的機制,如互斥鎖(Mutex)和通道(Channel)。

二、創(chuàng)建線程

1.創(chuàng)建一個線程

use std::thread;  
  
fn main() {  
    // 創(chuàng)建一個新線程  
    let handle = thread::spawn(|| {  
        // 在新線程中執(zhí)行的代碼  
        println!("Hello from a new thread!");  
    });  
  
    // 等待線程結(jié)束  
    handle.join().unwrap();  
}

2.創(chuàng)建多個線程

use std::thread;  

fn main() {  
    // 創(chuàng)建一個向量來存儲線程的句柄  
    let mut threads = vec![];  
    
    // 創(chuàng)建多個線程  
    for i in 0..5 {  
        // 使用閉包捕獲變量i的值  
        let thread_number = i;  
        let handle = thread::spawn(move || {  
            // 在新線程中打印線程編號  
            println!("線程 {} 正在運行", thread_number);  
        });  
    
        // 將線程句柄添加到向量中  
        threads.push(handle);  
    }  
    
    // 等待所有線程完成  
    for handle in threads {  
        handle.join().unwrap();  
    }  

    // 在主線程中打印一些信息  
    for i in 0..5 {  
        println!("主線程打印數(shù)字: {}", i);  
    }  
}

# 輸出結(jié)果:
線程 0 正在運行
線程 1 正在運行
線程 2 正在運行
線程 3 正在運行
線程 4 正在運行
主線程打印數(shù)字: 0
主線程打印數(shù)字: 1
主線程打印數(shù)字: 2
主線程打印數(shù)字: 3
主線程打印數(shù)字: 4
  • 從輸出結(jié)果上看,仍然像是順序執(zhí)行,所以這里引入一個休眠,讓線程執(zhí)行的時候隨機休眠0-3秒。

生成隨機數(shù)

由于Rust核心語言中沒有隨機數(shù)生成的函數(shù),需要使用rand庫來進行

# 首先需要在Cargo.toml中添加以下內(nèi)容
[dependencies]  
rand = "0.8"

# 然后在代碼中用use 引入
use rand::Rng;  
use rand::thread_rng;  
  
fn main() {  
    let mut rng = thread_rng();  
    for _i in 0..10{
        let random_number = rng.gen_range(1..4);  
        println!("隨機數(shù)是: {}", random_number);  
    }
}
# 結(jié)果:
隨機數(shù)是: 3
隨機數(shù)是: 1
隨機數(shù)是: 3
隨機數(shù)是: 1
隨機數(shù)是: 3
隨機數(shù)是: 1
隨機數(shù)是: 3
隨機數(shù)是: 2
隨機數(shù)是: 3
隨機數(shù)是: 1

隨機數(shù)生成的區(qū)間與循環(huán)一樣,是一個前閉后開的區(qū)間

嘗試讓程序睡一會兒

use rand::Rng;  
use std::{thread::sleep, time::Duration};  
  
fn main() {  
    // 創(chuàng)建一個隨機數(shù)生成器  
    let mut rng = rand::thread_rng();  
    // 生成一個0到3之間的隨機秒數(shù)  
    let random_seconds: u64 = rng.gen_range(0..4);  
    // 將秒數(shù)轉(zhuǎn)換為Duration  
    let duration = Duration::from_secs(random_seconds);  
    // 讓當(dāng)前線程睡眠指定的時間  
    sleep(duration);  
    // 之后的代碼會在等待后執(zhí)行  
    println!("等待了 {} 秒", random_seconds);  
}

引入多線程

use rand::Rng;  
use std::{thread::sleep, time::Duration};  
use std::thread;  

fn main() {  
    // 創(chuàng)建一個向量來存儲線程的句柄  
    let mut threads = vec![];  
    
    // 創(chuàng)建多個線程  
    for i in 1..=10 {  
        // 使用閉包捕獲變量i的值  
        let thread_number = i;  
        let handle = thread::spawn(move || {  
            // 在新線程中打印線程編號  
            println!("線程 {} 正在運行", thread_number);      
            // 創(chuàng)建一個隨機數(shù)生成器  
            let mut rng = rand::thread_rng();  
            // 生成一個0到3之間的隨機秒數(shù)  
            let random_seconds: u64 = rng.gen_range(0..4);  
            // 將秒數(shù)轉(zhuǎn)換為Duration  
            let duration = Duration::from_secs(random_seconds);  
            // 讓當(dāng)前線程睡眠指定的時間  
            sleep(duration);  
            println!("線程 {} 運行結(jié)束,休息了{}秒.", thread_number,random_seconds);  
        });  
    
        // 將線程句柄添加到向量中  
        threads.push(handle);  
    }  
    
    // 等待所有線程完成  
    for handle in threads {  
        handle.join().unwrap();  
    }  

    // 在主線程中打印一些信息  
    for i in 0..5 {  
        println!("主線程打印數(shù)字: {}", i);  
    }  
}

# 輸出結(jié)果
線程 3 正在運行
線程 2 正在運行
線程 5 正在運行
線程 7 正在運行
線程 7 運行結(jié)束,休息了0.
線程 4 正在運行
線程 6 正在運行
線程 1 正在運行
線程 8 正在運行
線程 9 正在運行
線程 10 正在運行
線程 6 運行結(jié)束,休息了1.
線程 4 運行結(jié)束,休息了1.
線程 3 運行結(jié)束,休息了1.
線程 9 運行結(jié)束,休息了1.
線程 1 運行結(jié)束,休息了2.
線程 10 運行結(jié)束,休息了2.
線程 5 運行結(jié)束,休息了2.
線程 2 運行結(jié)束,休息了3.
線程 8 運行結(jié)束,休息了3.
主線程打印數(shù)字: 0
主線程打印數(shù)字: 1
主線程打印數(shù)字: 2
主線程打印數(shù)字: 3
主線程打印數(shù)字: 4

三、線程返回值的處理

對于有返回值的多線程來說有兩種情況,一種是每個線程處理一個獨立的值,用向量接收,另一種是多個線程處理一個值。

1.每個線程處理一個獨立的值

use std::thread;  
  
fn main() {  
    let mut handles = vec![];  
  
    for i in 0..5 {  
        let handle = thread::spawn(move || {  
            return i*i;
        });  
        handles.push(handle);  
    }  
  
    let mut results = vec![];  
  
    for handle in handles {  
        match handle.join() {  
            Ok(value) => results.push(value),  
            Err(e) => println!("Thread panicked: {:?}", e),  
        }  
    }  
  
    println!("Results: {:?}", results);  //Results: [0, 1, 4, 9, 16]
}

2.多個線程處理一個值

由于多個線程處理一個值,可能造成條件競爭,屬于線程不安全行為,Rust語言中提供了3種處理行為。

  • Arc 只讀訪問,用于共享只讀數(shù)據(jù),通過原子引用計數(shù)管理生命周期。
  • Mutex 互斥鎖,用于保護數(shù)據(jù),確保一次只有一個線程可以訪問數(shù)據(jù)(提供獨占訪問)。
  • RwLock 讀寫鎖,用于保護數(shù)據(jù),但允許多個讀者同時訪問,寫者必須獨占訪問。

Arc(原子引用計數(shù))

Arc是一個提供共享所有權(quán)的智能指針。它用于在多個所有者之間共享數(shù)據(jù),且只允許對這些數(shù)據(jù)進行只讀訪問。Arc通過原子操作維護一個引用計數(shù),確保數(shù)據(jù)的生命周期至少與最長的所有者一樣長。當(dāng)最后一個Arc指針被丟棄時,其指向的數(shù)據(jù)也會被釋放。

use std::sync::Arc;  
use std::thread;  
  
fn main() {  
    // 創(chuàng)建一個要在多個線程之間共享的值  
    let data = Arc::new(vec![1, 2, 3, 4, 5]);  
  
    // 創(chuàng)建一個向量來存儲線程的句柄  
    let mut handles = vec![];  
    println!("Thread {:?} is reading value: {:?}", thread::current().id(), &data); // 主線程的線程ID為 1
    // 創(chuàng)建幾個線程來只讀訪問數(shù)據(jù)  
    for _i in 0..data.len() {  
        let data = data.clone(); // 克隆Arc以便在線程中使用  
        let handle = thread::spawn(move || {  
            // 獲取Vec的引用以便索引  
            // 使用 {:?} 來打印 ThreadId  
            println!("Thread {:?} is reading value: {:?}", thread::current().id(), &data);  
        });  
        handles.push(handle);  
    }  
  
    // 等待所有線程完成  
    for handle in handles {  
        handle.join().unwrap();  
    }  
}
# 運行結(jié)果
Thread ThreadId(1) is reading value: [1, 2, 3, 4, 5]
Thread ThreadId(2) is reading value: [1, 2, 3, 4, 5]
Thread ThreadId(3) is reading value: [1, 2, 3, 4, 5]
Thread ThreadId(4) is reading value: [1, 2, 3, 4, 5]
Thread ThreadId(5) is reading value: [1, 2, 3, 4, 5]
Thread ThreadId(6) is reading value: [1, 2, 3, 4, 5]

Mutex(互斥鎖)

Mutex是一個提供互斥訪問的智能指針。它用于保護數(shù)據(jù),確保一次只有一個線程能夠訪問數(shù)據(jù)。當(dāng)一個線程擁有Mutex的鎖時,其他嘗試獲取鎖的線程將被阻塞,直到鎖被釋放。

use std::sync::{Arc, Mutex};  
use std::thread;  
  
fn main() {  
    // 創(chuàng)建一個Arc包裹的互斥鎖和值  
    let counter = Arc::new(Mutex::new(1));  
    let mut handles = vec![];  
  
    // 創(chuàng)建幾個線程來增加計數(shù)器  
    for i in 1..10 {  
        // 克隆Arc智能指針,而不是Mutex或它的值  
        let counter = Arc::clone(&counter);  
        let handle = thread::spawn(move || {  
            // 獲取互斥鎖以便修改值  
            let mut num = counter.lock().unwrap();  
            *num *=i;
        });  
        handles.push(handle);  
    }  
  
    // 等待所有線程完成  
    for handle in handles {  
        handle.join().unwrap();  
    }  
  
    // 輸出最終計數(shù)器的值  
    println!("Result: {}", *counter.lock().unwrap());  // Result: 362880
}

RwLock(讀寫鎖)

RwLock是一個提供讀寫鎖定的智能指針。與Mutex不同,RwLock允許多個讀者同時訪問數(shù)據(jù),但寫者必須獨占鎖。當(dāng)寫者擁有鎖時,任何嘗試獲取讀鎖或?qū)戞i的線程都將被阻塞。當(dāng)沒有寫者時,可以有多個讀者同時訪問數(shù)據(jù)。

use std::sync::{Arc, RwLock};  
  
fn main() {  
    let data = Arc::new(RwLock::new(0));  
    let mut handles = vec![];  
  
    // 創(chuàng)建多個讀線程  
    for i in 0..5 {  
        let data = Arc::clone(&data);  
        let handle = std::thread::spawn(move || {  
            let num = data.read().unwrap();  
            println!("Thread {} Reading value: {}", i,*num);  
        });  
        handles.push(handle);  
    }  
  
    // 創(chuàng)建一個寫線程  
    let data = Arc::clone(&data);  
    let handle = std::thread::spawn(move || {  
        let mut num = data.write().unwrap();  
        *num += 1;  
        println!("Writing value: {}", *num);  
    });  
    handles.push(handle);  
  
    for handle in handles {  
        handle.join().unwrap();  
    }  
}
# 第一次執(zhí)行結(jié)果
Thread 0 Reading value: 0
Thread 3 Reading value: 0
Thread 1 Reading value: 0
Thread 4 Reading value: 0
Thread 2 Reading value: 0
Writing value: 1
# 第二次執(zhí)行結(jié)果
Thread 0 Reading value: 0
Thread 3 Reading value: 0
Thread 1 Reading value: 0
Thread 4 Reading value: 0
Thread 2 Reading value: 0
Writing value: 1

這里有一個問題,就是如果寫線程最后執(zhí)行,那么讀線程讀的都是原始數(shù)據(jù),如果寫線程先執(zhí)行,那么讀的就是修改后的數(shù)據(jù),所以對讀寫順序有要求的話應(yīng)該做好時序的控制文章來源地址http://www.zghlxwxcb.cn/news/detail-835161.html

到了這里,關(guān)于Rust語言之多線程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Rust多線程編程

    rust標(biāo)準(zhǔn)庫中提供了線程相關(guān)支持,直接引用即可使用: 使用spawn方法創(chuàng)建一個線程。如: 創(chuàng)建后線程自動運行: 默認(rèn)的spawn方法傳遞不了參數(shù)。如果要為線程傳遞參數(shù),需要使用匿名函數(shù)作為spawn的參數(shù),匿名函數(shù)也稱為閉包。 閉包(匿名函數(shù)) 閉包的基本語法: 使用閉包

    2024年02月11日
    瀏覽(24)
  • rust學(xué)習(xí)-線程

    Rust 標(biāo)準(zhǔn)庫只提供了 1:1 線程模型 Rust 是較為底層的語言,如果愿意犧牲性能來換取抽象,以獲得對線程運行更精細(xì)的控制及更低的上下文切換成本,使用實現(xiàn)了 M:N 線程模型的 crate 在參數(shù)列表前使用 move 強制閉包獲取其使用的環(huán)境值的所有權(quán)。 這個技巧在創(chuàng)建新線程

    2024年02月16日
    瀏覽(12)
  • 【rust語言】rust多態(tài)實現(xiàn)方式

    學(xué)習(xí)rust當(dāng)中遇到了這個問題,記錄一下,不對地方望指正 多態(tài)是面向?qū)ο蟪绦蛟O(shè)計中的一個重要概念,指同一個行為或操作在不同實例上具有不同的行為或結(jié)果。簡單來說,多態(tài)就是指同一種類型的對象,在不同的上下文中有不同的行為。多態(tài)性使得程序可以更加靈活、可

    2024年02月11日
    瀏覽(28)
  • rust寫一個多線程和協(xié)程的例子

    當(dāng)涉及到多線程和協(xié)程時,Rust提供了一些非常強大的工具,其中最常用的庫之一是 tokio ,它用于異步編程和協(xié)程。下面我將為你展示一個簡單的Rust程序,演示如何使用多線程和協(xié)程。 首先,你需要在你的項目的 Cargo.toml 文件中添加 tokio 庫的依賴: [dependencies] tokio = { versi

    2024年02月11日
    瀏覽(19)
  • Rust 實現(xiàn)線程安全的 Lock Free 計數(shù)器

    完整代碼:https://github.com/chiehw/hello_rust/blob/main/crates/counter/src/lib.rs Trait 可以看作是一種 能力的抽象 ,和接口有點類似。Trait 還能作為 泛型約束條件 ,作為參數(shù)的限制條件。 使用測試驅(qū)動開發(fā)可以讓目標(biāo)更明確,這里先寫個簡單的測試案例。 直接封裝 AtomicUsize 使用多線程

    2024年04月13日
    瀏覽(14)
  • C語言和Rust語言的互相調(diào)用(2)(Rust調(diào)用C)

    1.創(chuàng)建項目 rust調(diào)用c方式挺多的,這里采用最通俗易懂的方法,用構(gòu)建腳本進行構(gòu)建整個項目。 2.編輯build.rs的內(nèi)容 這里的build.rs:若要創(chuàng)建構(gòu)建腳本,我們只需在項目的根目錄下添加一個 build.rs 文件即可。這樣一來, Cargo 就會先編譯和執(zhí)行該構(gòu)建腳本,然后再去構(gòu)建整個項

    2024年02月02日
    瀏覽(23)
  • 【Rust 基礎(chǔ)篇】Rust FFI:連接Rust與其他編程語言的橋梁

    Rust是一種以安全性和高效性著稱的系統(tǒng)級編程語言,具有出色的性能和內(nèi)存安全特性。然而,在現(xiàn)實世界中,我們很少有項目是完全用一種編程語言編寫的。通常,我們需要在項目中使用多種編程語言,特別是在與現(xiàn)有代碼庫或底層系統(tǒng)交互時。為了實現(xiàn)跨語言的互操作性,

    2024年02月15日
    瀏覽(29)
  • Rust 筆記:Rust 語言中的常量與變量

    Rust 筆記 Rust 語言中的常量與變量 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343 郵箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/130875912 【介紹】:本文介紹 Rust 語言中的常量與變量。 上一節(jié):《 上一節(jié)標(biāo)題 》 | 下一節(jié):《

    2024年02月06日
    瀏覽(21)
  • Rust 筆記:Rust 語言中的字符串

    Rust 筆記 Rust 語言中的字符串 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343 郵箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/130876665 【介紹】:本文介紹 Rust 語言中的字符和字符串的用法。 上一節(jié):《 Rust 語言中使用 vector(向

    2024年02月06日
    瀏覽(18)
  • 【Rust】Rust學(xué)習(xí) 第十三章Rust 中的函數(shù)式語言功能:迭代器與閉包

    【Rust】Rust學(xué)習(xí) 第十三章Rust 中的函數(shù)式語言功能:迭代器與閉包

    Rust 的設(shè)計靈感來源于很多現(xiàn)存的語言和技術(shù)。其中一個顯著的影響就是? 函數(shù)式編程 ( functional programming )。函數(shù)式編程風(fēng)格通常包含將函數(shù)作為參數(shù)值或其他函數(shù)的返回值、將函數(shù)賦值給變量以供之后執(zhí)行等等。 更具體的,我們將要涉及: 閉包 ( Closures ),一個可以儲

    2024年02月12日
    瀏覽(32)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包