Rust:并发编程(concurrent programming)
得益于所有權系統以及類型系統,Rust有著非常優異的并發性能。
1. 線程的基本應用
創建線程:
use std::thread; use std::time::Duration; fn main() {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));} } 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 main thread! hi number 3 from the spawned thread! hi number 4 from the spawned thread! hi number 4 from the main thread! hi number 5 from the spawned thread!需要注意的是,當主線程結束,不管thread::spawn創建的子線程是否執行完畢,程序都會結束。所以子線程的print語句只執行到了i=5。
使用Join()讓主線程等待子線程執行完畢:
如果我們想讓子線程執行完畢,可以將thread::spawn賦給變量,然后調用join。在rust中,thread::spawn返回的type是JoinHandle。
use std::thread; use std::time::Duration; fn main() {//thread::spawn創建線程后返回JoinHandle 類型給handlelet 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));}//調用join,讓主線程等待至子線程執行完畢//unwrap的作用:請求返回結果,如果報錯就會panic并停止程序handle.join().unwrap(); } hi number 1 from the main thread! hi number 2 from the main thread! hi number 1 from the spawned thread! hi number 3 from the main thread! hi number 2 from the spawned thread! hi number 4 from the main thread! hi number 3 from the spawned 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!使用Move讓線程獲得變量所有權
在Rust里,當閉包函數使用外界環境的變量時,編譯器會推斷閉包函數該采用借用,還是獲取變量所有權的方式。當創建的子線程需要使用主線程的數據時,由于閉包函數運行子線程環境中而無法確定借用是否一直有效,所以需要使用move來使變量所有權移交至子線程的閉包函數。
use std::thread; fn main() {let v = vec![1, 2, 3];//使用move移交所有權至子線程let handle = thread::spawn(move|| {println!("Here's a vector: {:?}", v);});handle.join().unwrap(); }2. 線程通信機制:channel,transmitter與receiver
Rust book中將rust的線程通信的channel比作一條河,數據比作橡皮鴨。橡皮鴨從上游(transmitter)順流而下到下游(receiver)。Rust中實現線程通信的標準庫為mpsc,是multiple producer; single consumer的縮寫。意思是在rust線程通信機制中,可以有多個數據發送端,然后像河流匯聚到大海一般,最終由一個接受端接收。
use std::thread; use std::sync::mpsc; fn main() {//創建channel//mpsc::channel()返回一個tuple,包含transmitter:tx , receiver:rx//在很多領域tx,rx都被當做是transmitter與receiver的縮寫//所以rust book的這個例子也以此來命名let (tx, rx) = mpsc::channel();thread::spawn(move || {let val = String::from("hi");//transmitter從子線程發送數據tx.send(val).unwrap();//需要注意的是,此時val的所有權也被移交給了數據的接收線程});//主線程接受子線程數據let received = rx.recv().unwrap();println!("Got: {}", received); } Got: hiSending Multiple Values and Seeing the Receiver Waiting:
為了直觀展現出兩個線程通過channel保持communicating,對上述代碼做出一點修改:使用for循環發送多條value,并且每次發送間隔1秒。同樣也以for循環在主線程中接收數據,這時rx被當作一個iterator。每當接收到一條數據,for循環就會執行一次。直到數據發送完畢,channel關閉。
use std::thread; use std::sync::mpsc; use std::time::Duration; fn main() {let (tx, rx) = mpsc::channel();thread::spawn(move || {let vals = vec![String::from("hi"),String::from("from"),String::from("the"),String::from("thread"),];for val in vals {tx.send(val).unwrap();thread::sleep(Duration::from_secs(1));}});for received in rx {println!("Got: {}", received);} }應該可以直觀的看到每條數據之間都間隔了1秒。
Got: hi Got: from Got: the Got: thread使用clone函數實現mpsc: multiple producer; single consumer
use std::thread; use std::sync::mpsc; use std::time::Duration; fn main() {let (tx, rx) = mpsc::channel();//使用clone函數clone一個transmitterlet tx1 = mpsc::Sender::clone(&tx);thread::spawn(move || {let vals = vec![String::from("hi"),String::from("from"),String::from("the"),String::from("thread"),];for val in vals {tx.send(val).unwrap();thread::sleep(Duration::from_secs(1));}});thread::spawn(move || {let vals = vec![String::from("more"),String::from("messages"),String::from("for"),String::from("you"),];for val in vals {tx1.send(val).unwrap();thread::sleep(Duration::from_secs(1));}});for received in rx {println!("Got: {}", received);} } Got: hi Got: more Got: from Got: messages Got: the Got: for Got: you Got: thread總結
以上是生活随笔為你收集整理的Rust:并发编程(concurrent programming)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据标注去哪接任务订单?靠谱的数据标注平
- 下一篇: remix共享本地文件夹