Rust 多線程編程的實(shí)現(xiàn)
一個(gè)進(jìn)程一定有一個(gè)主線程,主線程之外創(chuàng)建出來的線程稱為子線程
多線程編程,其實(shí)就是在主線程之外創(chuàng)建子線程,讓子線程和主線程并發(fā)運(yùn)行,完成各自的任務(wù)。
Rust語言支持多線程編程。
Rust語言標(biāo)準(zhǔn)庫中的 std::thread 模塊用于多線程編程。
std::thread 提供很很多方法用于創(chuàng)建線程、管理線程和結(jié)束線程。
一、創(chuàng)建線程
使用std::thread::spawn()方法創(chuàng)建一個(gè)線程。
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
參數(shù) f 是一個(gè)閉包,是線程要執(zhí)行的代碼。
范例
use std::thread; // 導(dǎo)入線程模塊
use std::time::Duration; // 導(dǎo)入時(shí)間模塊
fn main() {
//創(chuàng)建一個(gè)新線程
thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
// 主線程要執(zhí)行的代碼
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));
}
}
編譯運(yùn)行結(jié)果如下
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the main thread!
hi number 2 from the spawned thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 4 from the main thread!
咦,執(zhí)行結(jié)果好像出錯(cuò)了? 是嗎?
當(dāng)主線程執(zhí)行結(jié)束,那么就會(huì)自動(dòng)關(guān)閉創(chuàng)建出來的子線程。
上面的代碼,我們調(diào)用 thread::sleep() 函數(shù)強(qiáng)制線程休眠一段時(shí)間,這就允許不同的線程交替執(zhí)行。
雖然某個(gè)線程休眠時(shí)會(huì)自動(dòng)讓出cpu,但并不保證其它線程會(huì)執(zhí)行。這取決于操作系統(tǒng)如何調(diào)度線程。
這個(gè)范例的輸出結(jié)果是隨機(jī)的,主線程一旦執(zhí)行完成程序就會(huì)自動(dòng)退出,不會(huì)繼續(xù)等待子線程。這就是子線程的輸出結(jié)果不全的原因。
二、讓主線程等待子線程
默認(rèn)情況下,主線程并不會(huì)等待子線程執(zhí)行完畢。為了避免這種情況,我們可以讓主線程等待子線程執(zhí)行完畢然后再繼續(xù)執(zhí)行。
Rust標(biāo)準(zhǔn)庫提供了 join() 方法用于把子線程加入主線程等待隊(duì)列。
spawn<F, T>(f: F) -> JoinHandle<T>
范例
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));
}
handle.join().unwrap();
}
編譯運(yùn)行結(jié)果如下
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 2 from the main thread!
hi number 3 from the spawned thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!
從輸出結(jié)果來看,主線程和子線程交替執(zhí)行。
主線程等待子線程執(zhí)行完畢是因?yàn)檎{(diào)用了 join() 方法。
三、move強(qiáng)制所有權(quán)遷移
這是一個(gè)經(jīng)常遇到的情況:
實(shí)例
use std::thread;
fn main() {
let s = "hello";
let handle = thread::spawn(|| {
println!("{}", s);
});
handle.join().unwrap();
}
在子線程中嘗試使用當(dāng)前函數(shù)的資源,這一定是錯(cuò)誤的!因?yàn)樗袡?quán)機(jī)制禁止這種危險(xiǎn)情況的產(chǎn)生,它將破壞所有權(quán)機(jī)制銷毀資源的一定性。我們可以使用閉包的move關(guān)鍵字來處理:
實(shí)例
use std::thread;
fn main() {
let s = "hello";
let handle = thread::spawn(move || {
println!("{}", s);
});
handle.join().unwrap();
}
四、消息傳遞
使用通道傳遞消息,通道有兩部分組成,一個(gè)發(fā)送者(transmitter)和一個(gè)接收者(receiver)。
std::sync::mpsc包含了消息傳遞的方法:
實(shí)例
use std::thread;
use std::sync::mpsc;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
}
運(yùn)行結(jié)果:
Got: hi
子線程獲得了主線程的發(fā)送者tx,并調(diào)用了它的send方法發(fā)送了一個(gè)字符串,然后主線程就通過對應(yīng)的接收者rx接收到了。
到此這篇關(guān)于Rust 多線程編程的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Rust 多線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Windows系統(tǒng)下安裝Rust環(huán)境超詳細(xì)教程
這篇文章主要介紹了如何在Windows系統(tǒng)上安裝mingw64和Rust,mingw64是一個(gè)輕便的C語言編譯環(huán)境,可以替代Rust默認(rèn)使用的Visual?Studio,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02
Rust?編程語言中的所有權(quán)ownership詳解
這篇文章主要介紹了Rust?編程語言中的所有權(quán)ownership詳解的相關(guān)資料,需要的朋友可以參考下2023-02-02
Rust?連接?PostgreSQL?數(shù)據(jù)庫的詳細(xì)過程
這篇文章主要介紹了Rust?連接?PostgreSQL?數(shù)據(jù)庫的完整代碼,本文圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01
rust多樣化錯(cuò)誤處理(從零學(xué)習(xí))
一個(gè)優(yōu)秀的項(xiàng)目,錯(cuò)誤處理的優(yōu)雅性是至關(guān)重要的,而rust,anyhow creat是繞不過去的一個(gè),今天我們來研究下,怎么使用它,幫助我們寫出更優(yōu)雅的代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2023-11-11

