rust学习_并发编程

rust并发编程的几个概念1.线程
     1.线程是操作系统调度的
基本单位,可独立执行任务
     2. rust提供了 std::thread 模块,用于创建和管理线程

2.所有权和借用
     1.rust通过所有权和借用机制来确保
内存安全
     2.在并发环境下,所有权和借用规则有助于防止数据竞争等问题 

3.原子操作
     1.原子操作可以在多线程下安全更新共享数据
     2.使用 std::sync::atomic 实现原子操作

4.通道
      1.通道提供一种在
多线程间传递消息的机制,有助于实现无锁编程
      2.rust提供了 std::sync::mpsc模块,用于实现线程间的通信
          mpsc:Multiple Producer ,Single Consumter  
多个生产者线程发送消息到一个 通道,单个消费者线程接受该通道信息

5.Arc(Atomic Refrence Counting)
      1.Arc可以在多个线程间共享数据 同时提供
引用计数来管理生命周期
      2.rust提供了 std::sync::Arc 用于实现多线程环境下智能指针
      解释
        1.什么是自动引用计数
            每创建一个对象,系统会该对象分配一个计数器,每当有一个新的引用指向该对象时,
计数器就会增加
            当引用不再存在时,计数器就会减少 
rust并发编程示例_创建线程use std::thread;
use std::time::Duration;

fn main() {
    println!("Hello from the main thread!");

    // 创建一个新的线程
    let handle = thread::spawn(|| {      //spawn:生成,创建。它接受一个必包作为参数,定义了新线程将要执行的代码
                                           //     || : 作为必包的参数分隔符   ||表示该必包不接受任何参数
        for i in 1..10 {
            println!("Hello from the spawned thread! {}", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    // 等待新线程结束
    handle.join()
.unwrap(); //unwarp:解包,展开

    println!("Back to the main thread!");
}
rust并发编程示例_使用通道传递消息use std::sync::mpsc;
use std::thread;

fn main() {
    // 创建一个通道
    let (tx, rx) = mpsc::channel();

    // 创建一个线程来发送消息
    let tx1 = tx.
clone();
    thread::spawn(
move || { //move:当一个必包通过move关键字捕获变量时,它将取得这些变量的所有权
        let vals = vec![   //vec! 创建向量
            String::from("hello"),
            String::from("world"),
        ];
        for val in vals {
            tx1.
send(val).unwrap();
            thread::sleep(std::time::Duration::from_secs(1));
        }
    });

    thread::spawn(move || {
        let vals = vec![
            String::from("foo"),
            String::from("bar"),
        ];
        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(std::time::Duration::from_secs(1));
        }
    });

    // 接收消息
    for received in
 rx {
        println!("Got: {}", received);
    }
}
rust并发编程示例_使用Arc实现共享数据use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0)); //创建共享计数器   用 Arc 来允许这个互斥锁的所有权在多个线程之间共享
         //1.Mutext::new(0) :创建一个互斥锁,它内部包含了一个初始值为0的整数
               //比喻:你有一个数字(初始值是 0),并且你把它放在一个保险箱(互斥锁)里,这样只有拥有钥匙(锁)的人才能打开它并修改里面的数字。
         //2.Arc::new:增加引用计数,每个线程都有自己的数据引用
               //比喻:然后,你制作了这个保险箱的多个副本(使用 Arc),每个副本都可以被一个线程安全地使用,而原始的数字始终保持一致和安全。

    let mut handles = 
Vec::new();   //存储每个新创建的线程的句柄
          //1.Vec::new() 创建了一个空的动态数组。动态数组可以存储一系列的元素,并且可以根据需要
自动增长或缩小
          //比喻:创建了一个名为 handles 的新盒子(变量),并且这个盒子是可变的,意味着你可以往里面放东西或者把里面的东西拿出来。
                    //这个盒子(handles)目前是空的,但它是专门用来存放“句柄”的。

    for _ in 0..10 {
        let counter_clone = 
Arc::clone(&counter); // Arc::clone 方法来增加 Arc 的引用计数,这样每个线程都可以拥有 counter 的一个引用
        let handle = thread::spawn(move || {
            let mut num = counter_clone.lock().unwrap(); 使用 lock 方法来获取互斥锁,这会阻塞当前线程直到锁可用
            *num += 1; //一旦获取了互斥锁,就增加包装在互斥锁内部的计数器的值
        });
        handles.push(handle); //将新线程的句柄添加到 handles 向量中。
    }

    for handle in handles {
        handle.join().unwrap(); //使用 join 方法等待每个线程完成
    }

    println!("Final count: {}", *counter.lock().unwrap()); //再次获取互斥锁,打印出最终的计数器值
    //unwrap():这个方法用于处理 Result 类型。在这个上下文中,lock() 方法返回的是一个 Result 类型,它可以是 Ok,表示成功获取了锁,或者 Err,表示在尝试获取锁时发生了错误。unwrap() 方法会检查 Result,如果是 Ok,它会返回里面的值(在这个例子中是锁住的计数器),如果是 Err,程序将会 panic(即异常终止)
}
Arc上述代码解释(比喻)

 想象一下,你有一个特殊的计数器(就像一个可以计数的魔法盒子),这个计数器放在一个保险箱里,这样只有拥有钥匙的人才能打开它并改变里面的数字。现在,你想让10个朋友在不同的房间里同时增加这个计数器的值,而且每个人只能增加一次。

以下是这段代码的步骤:

创建一个计数器和一把锁:
let counter = Arc::new(Mutex::new(0));
这行代码创建了一个初始值为0的计数器,并且把它放在一个互斥锁(Mutex)里,这样可以确保一次只有一个朋友能改变计数器的值。
然后,使用 Arc(原子引用计数)来创建这个计数器的一个安全副本,这样多个朋友(线程)都可以拥有这个计数器的引用,而不会担心数据的安全问题。

 

准备一个空列表来存放朋友的遥控器(线程句柄):
let mut handles = Vec::new();
这行代码创建了一个空的列表,用来存放每个朋友房间的遥控器。遥控器可以用来在最后确认朋友是否已经完成了增加计数器的任务。

 

创建10个朋友(线程)来增加计数器的值:
for _ in 0..10 { ... }
这个循环会执行10次,每次都创建一个新的朋友(线程)。
在循环内部,每个朋友都获得了一个计数器副本的遥控器(Arc::clone(&counter)),并且通过 thread::spawn 创建了一个新的线程。

 

在新线程中,朋友会先打开保险箱(counter_clone.lock().unwrap()),然后增加计数器的值(*num += 1;),最后保险箱会自动上锁。
 

等待所有朋友完成增加计数器的任务:
for handle in handles { handle.join().unwrap(); }
这行代码遍历列表中的所有遥控器,并使用 join 方法等待每个朋友完成他们的任务。这就像是在每个房间外等待,直到朋友告诉你他们已经完成了增加计数器的任务。

 

打印最终的计数器值:
println!("Final count: {}", *counter.lock().unwrap());
最后,打开保险箱,查看计数器的最终值,并打印出来。这个值应该是10,因为每个朋友都增加了1。

 

总的来说,这段代码展示了如何在 Rust 中使用多线程安全地增加一个共享计数器的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

simper_zxb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值