rust并发

文章目录

Rust对多线程的支持

rust默认仅支持一对一线程,也就是说操作系统线程。

可以引入crate包来使用绿色线程。

std::thread::spawn创建线程

rust 复制代码
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();
}

编译

bash 复制代码
 cargo run
warning: unused `Result` that must be used
  --> src/main.rs:17:5
   |
17 |     handle.join();
   |     ^^^^^^^^^^^^^
   |
   = note: this `Result` may be an `Err` variant, which should be handled
   = note: `#[warn(unused_must_use)]` on by default
help: use `let _ = ...` to ignore the resulting value
   |
17 |     let _ = handle.join();
   |     +++++++

warning: `smartPtr` (bin "smartPtr") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/smartPtr`
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 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!

线程与 move 闭包

rust 复制代码
use std::thread;

fn main() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
    });

    handle.join().unwrap();
}

编译

rust 复制代码
 cargo run
    Blocking waiting for file lock on build directory
   Compiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.07s
     Running `target/debug/smartPtr`
Here's a vector: [1, 2, 3]

使用消息传递在线程间传送数据

std::sync::mpsc::channel()

只支持多个生产者和一个消费者

rust 复制代码
use std::sync::mpsc; //mpsc:multi-producer, single-consumer
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });

    // recv()会阻塞
    // try_recv()是非阻塞,适合使用loop来尝试接收
    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}

for received in rx接收

rust 复制代码
use std::sync::mpsc;
use std::thread;
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));
        }
    });

    // 当发送方tx结束了,接收方rx就会结束(for循环也会结束)
    for received in rx {
        println!("Got: {}", received);
    }
}

两个producer

rust 复制代码
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    // --snip--

    let (tx, rx) = mpsc::channel();

    let tx1 = tx.clone(); //tx和tx1都连接到mpsc::channel()
    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx1.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 {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {}", received);
    }

    // --snip--
}

共享状态并发

std::sync::Mutex

rust 复制代码
use std::sync::Mutex;

fn main() {
    let m = Mutex::new(5);

    {
        // m.lock()会阻塞当前线程,获取锁位置
        let mut num = m.lock().unwrap();
        *num = 6;
        // 退出时会自动释放锁
    }

    println!("m = {:?}", m);
}

编译及运行

bash 复制代码
 cargo run
   Compiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.57s
     Running `target/debug/smartPtr`
m = Mutex { data: 6, poisoned: false, .. }

在多个线程间共享Mutex,使用std::sync::Arc

rust 复制代码
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;

fn main() {
    // Mutex于Arc经常一起使用
    // Rc::new可以让Mutex拥有多个所有者
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter); //Rc::clone不是真正的clone,只是增加引用计数
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap(); //counter.lock()可以获得可变的引用(类似于RefCell智能指针)

            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}

编译

bash 复制代码
 cargo run
   Compiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.85s
     Running `target/debug/smartPtr`
Result: 10

参考

相关推荐
前端与小赵16 小时前
什么是Sass,有什么特点
前端·rust·sass
一个小坑货16 小时前
Rust基础
开发语言·后端·rust
Object~17 小时前
【第九课】Rust中泛型和特质
开发语言·后端·rust
码农飞飞20 小时前
详解Rust结构体struct用法
开发语言·数据结构·后端·rust·成员函数·方法·结构体
Dontla2 天前
Rust derive macro(Rust #[derive])Rust派生宏
开发语言·后端·rust
fqbqrr2 天前
2411rust,编译时自动检查配置
rust
梦想画家2 天前
用Rust中byteorder包高效处理字节序列
rust·序列化·byteorder·文件编码
beifengtz2 天前
【Rust调用Windows API】读取系统CPU利用率
windows·rust·windows api
梦想画家2 天前
精通Rust系统教程-过程宏入门
rust·元编程·rust宏
fqbqrr2 天前
2411rust,1.81,1.82
rust