searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

rust多线程基础学习

2025-10-29 10:31:59
0
0

1. 线程基础

创建线程:

use std::thread;
use std::time::Duration;

fn test1() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("{}", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    handle.join().unwrap(); // 等待线程结束
}

使用move关键字:

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

    // move 强制闭包获取外部变量所有权
    let handle = thread::spawn(move || {
        for i in v.iter() {
            println!("{}", i);
        }
    });

    handle.join().unwrap();
}

关键点:

  • thread::spawn 创建新线程
  • join() 等待线程完成
  • move 关键字将外部变量所有权转移到闭包中

2. 消息传递并发

通道基础:

use std::sync::mpsc; // multiple producer, single consumer

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

    let handle = thread::spawn(move || {
        let value = String::from("hello");
        thread::sleep(Duration::from_millis(10000));
        match tx.send(value) {
            Result::Ok(_) => println!("done"),
            Result::Err(e) => println!("error {}", e),
        }
    });

    let received = match rx.try_recv() {
        Result::Ok(val) => val,
        Result::Err(e) => panic!("NO EXISTING MESSAGE! ERROR: {}", e),
    };
    println!("Got: {}", received);
}

所有权转移:

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

    let handle = thread::spawn(move || {
        let value = String::from("hello");
        tx.send(value).unwrap();
        // 发送后不能再使用 value,所有权已转移!
        // println!("sent: {}", value); // 这行会编译错误
    });

    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}

多个值发送:

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

    let handle = thread::spawn(move || {
        let values = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for value in values.into_iter() {
            tx.send(value).unwrap();
            thread::sleep(Duration::from_millis(2000));
        }
    });

    for value in rx.iter() {
        println!("Got: {}", value);
    }
}

消息传递特点:

  • mpsc::channel() 创建发送端和接收端
  • send() 转移值的所有权
  • recv() 阻塞等待,try_recv() 非阻塞
  • 通道自动在发送/接收端被丢弃时关闭

3. 共享状态并发

互斥锁基础:

fn test6() {
    let data = Mutex::new(5);
    {
        // 获取锁,阻塞直到获得锁
        let mut m = data.lock().unwrap();
        *m += 10;
    } // 离开作用域自动释放锁
    println!("data: {:?}", data);
}

多线程共享Mutex:

fn test7() {
    let data = Arc::new(Mutex::new(5));
    let mut v = vec![];
    
    for _ in 0..5 {
        let data = Arc::clone(&data);
        let handle = thread::spawn(move || {
            let mut number = data.lock().unwrap();
            *number += 10;
        });
        v.push(handle);
    }

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

    println!("{:?}", data);
}

共享状态关键点:

  • Mutex<t> 提供内部可变性
  • 访问数据之前必须调用 lock() 获取锁
  • Arc<t> 是线程安全的引用计数指针
  • Rc<t> 不能在多线程中使用

4. 死锁

尝试自己编写一个死锁的案例:

fn dead_lock() {
    let data1 = Arc::new(Mutex::new(5));
    let data2 = Arc::new(Mutex::new(10));

    let data11 = Arc::clone(&data1);
    let data22 = Arc::clone(&data2);
    // 线程1:先锁 data1,再锁 data2
    let handle1 = thread::spawn(move || {
        let mut number1 = data11.lock().unwrap();
        thread::sleep(Duration::from_millis(500));
        let mut number2 = data22.lock().unwrap(); // 可能阻塞在这里

        println!("number1: {:?}", number1);
        println!("number2: {:?}", number2);
    });

    let data111 = Arc::clone(&data1);
    let data222 = Arc::clone(&data2);
    // 线程2:先锁 data2,再锁 data1  
    let handle2 = thread::spawn(move || {
        let mut number2 = data222.lock().unwrap();
        thread::sleep(Duration::from_millis(500));
        let mut number1 = data111.lock().unwrap(); // 可能阻塞在这里

        println!("number1: {:?}", number1);
        println!("number2: {:?}", number2);
    });

    handle1.join().unwrap();
    handle2.join().unwrap();
}
0条评论
作者已关闭评论
陈****然
6文章数
0粉丝数
陈****然
6 文章 | 0 粉丝
陈****然
6文章数
0粉丝数
陈****然
6 文章 | 0 粉丝
原创

rust多线程基础学习

2025-10-29 10:31:59
0
0

1. 线程基础

创建线程:

use std::thread;
use std::time::Duration;

fn test1() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("{}", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    handle.join().unwrap(); // 等待线程结束
}

使用move关键字:

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

    // move 强制闭包获取外部变量所有权
    let handle = thread::spawn(move || {
        for i in v.iter() {
            println!("{}", i);
        }
    });

    handle.join().unwrap();
}

关键点:

  • thread::spawn 创建新线程
  • join() 等待线程完成
  • move 关键字将外部变量所有权转移到闭包中

2. 消息传递并发

通道基础:

use std::sync::mpsc; // multiple producer, single consumer

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

    let handle = thread::spawn(move || {
        let value = String::from("hello");
        thread::sleep(Duration::from_millis(10000));
        match tx.send(value) {
            Result::Ok(_) => println!("done"),
            Result::Err(e) => println!("error {}", e),
        }
    });

    let received = match rx.try_recv() {
        Result::Ok(val) => val,
        Result::Err(e) => panic!("NO EXISTING MESSAGE! ERROR: {}", e),
    };
    println!("Got: {}", received);
}

所有权转移:

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

    let handle = thread::spawn(move || {
        let value = String::from("hello");
        tx.send(value).unwrap();
        // 发送后不能再使用 value,所有权已转移!
        // println!("sent: {}", value); // 这行会编译错误
    });

    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}

多个值发送:

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

    let handle = thread::spawn(move || {
        let values = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for value in values.into_iter() {
            tx.send(value).unwrap();
            thread::sleep(Duration::from_millis(2000));
        }
    });

    for value in rx.iter() {
        println!("Got: {}", value);
    }
}

消息传递特点:

  • mpsc::channel() 创建发送端和接收端
  • send() 转移值的所有权
  • recv() 阻塞等待,try_recv() 非阻塞
  • 通道自动在发送/接收端被丢弃时关闭

3. 共享状态并发

互斥锁基础:

fn test6() {
    let data = Mutex::new(5);
    {
        // 获取锁,阻塞直到获得锁
        let mut m = data.lock().unwrap();
        *m += 10;
    } // 离开作用域自动释放锁
    println!("data: {:?}", data);
}

多线程共享Mutex:

fn test7() {
    let data = Arc::new(Mutex::new(5));
    let mut v = vec![];
    
    for _ in 0..5 {
        let data = Arc::clone(&data);
        let handle = thread::spawn(move || {
            let mut number = data.lock().unwrap();
            *number += 10;
        });
        v.push(handle);
    }

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

    println!("{:?}", data);
}

共享状态关键点:

  • Mutex<t> 提供内部可变性
  • 访问数据之前必须调用 lock() 获取锁
  • Arc<t> 是线程安全的引用计数指针
  • Rc<t> 不能在多线程中使用

4. 死锁

尝试自己编写一个死锁的案例:

fn dead_lock() {
    let data1 = Arc::new(Mutex::new(5));
    let data2 = Arc::new(Mutex::new(10));

    let data11 = Arc::clone(&data1);
    let data22 = Arc::clone(&data2);
    // 线程1:先锁 data1,再锁 data2
    let handle1 = thread::spawn(move || {
        let mut number1 = data11.lock().unwrap();
        thread::sleep(Duration::from_millis(500));
        let mut number2 = data22.lock().unwrap(); // 可能阻塞在这里

        println!("number1: {:?}", number1);
        println!("number2: {:?}", number2);
    });

    let data111 = Arc::clone(&data1);
    let data222 = Arc::clone(&data2);
    // 线程2:先锁 data2,再锁 data1  
    let handle2 = thread::spawn(move || {
        let mut number2 = data222.lock().unwrap();
        thread::sleep(Duration::from_millis(500));
        let mut number1 = data111.lock().unwrap(); // 可能阻塞在这里

        println!("number1: {:?}", number1);
        println!("number2: {:?}", number2);
    });

    handle1.join().unwrap();
    handle2.join().unwrap();
}
文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0