Rust 多線程編程的實現
一個進程一定有一個主線程,主線程之外創(chuàng)建出來的線程稱為子線程
多線程編程,其實就是在主線程之外創(chuàng)建子線程,讓子線程和主線程并發(fā)運行,完成各自的任務。
Rust語言支持多線程編程。
Rust語言標準庫中的 std::thread 模塊用于多線程編程。
std::thread 提供很很多方法用于創(chuàng)建線程、管理線程和結束線程。
一、創(chuàng)建線程
使用std::thread::spawn()方法創(chuàng)建一個線程。
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
參數 f 是一個閉包,是線程要執(zhí)行的代碼。
范例
use std::thread; // 導入線程模塊 use std::time::Duration; // 導入時間模塊 fn main() { //創(chuàng)建一個新線程 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)); } } 編譯運行結果如下 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í)行結果好像出錯了? 是嗎?
當主線程執(zhí)行結束,那么就會自動關閉創(chuàng)建出來的子線程。
上面的代碼,我們調用 thread::sleep() 函數強制線程休眠一段時間,這就允許不同的線程交替執(zhí)行。
雖然某個線程休眠時會自動讓出cpu,但并不保證其它線程會執(zhí)行。這取決于操作系統(tǒng)如何調度線程。
這個范例的輸出結果是隨機的,主線程一旦執(zhí)行完成程序就會自動退出,不會繼續(xù)等待子線程。這就是子線程的輸出結果不全的原因。
二、讓主線程等待子線程
默認情況下,主線程并不會等待子線程執(zhí)行完畢。為了避免這種情況,我們可以讓主線程等待子線程執(zhí)行完畢然后再繼續(xù)執(zhí)行。
Rust標準庫提供了 join() 方法用于把子線程加入主線程等待隊列。
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(); } 編譯運行結果如下 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!
從輸出結果來看,主線程和子線程交替執(zhí)行。
主線程等待子線程執(zhí)行完畢是因為調用了 join() 方法。
三、move強制所有權遷移
這是一個經常遇到的情況:
實例
use std::thread; fn main() { let s = "hello"; let handle = thread::spawn(|| { println!("{}", s); }); handle.join().unwrap(); }
在子線程中嘗試使用當前函數的資源,這一定是錯誤的!因為所有權機制禁止這種危險情況的產生,它將破壞所有權機制銷毀資源的一定性。我們可以使用閉包的move關鍵字來處理:
實例
use std::thread; fn main() { let s = "hello"; let handle = thread::spawn(move || { println!("{}", s); }); handle.join().unwrap(); }
四、消息傳遞
使用通道傳遞消息,通道有兩部分組成,一個發(fā)送者(transmitter)和一個接收者(receiver)。
std::sync::mpsc包含了消息傳遞的方法:
實例
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); } 運行結果: Got: hi
子線程獲得了主線程的發(fā)送者tx,并調用了它的send方法發(fā)送了一個字符串,然后主線程就通過對應的接收者rx接收到了。
到此這篇關于Rust 多線程編程的實現的文章就介紹到這了,更多相關Rust 多線程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Windows系統(tǒng)下安裝Rust環(huán)境超詳細教程
這篇文章主要介紹了如何在Windows系統(tǒng)上安裝mingw64和Rust,mingw64是一個輕便的C語言編譯環(huán)境,可以替代Rust默認使用的Visual?Studio,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2025-02-02