当前位置: 首页 > news >正文

rust并发

文章目录

  • Rust对多线程的支持
      • std::thread::spawn创建线程
      • 线程与 move 闭包
    • 使用消息传递在线程间传送数据
      • std::sync::mpsc::channel()
      • for received in rx接收
      • 两个producer
  • 共享状态并发
    • std::sync::Mutex
    • 在多个线程间共享Mutex,使用std::sync::Arc
  • 参考

Rust对多线程的支持

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

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

std::thread::spawn创建线程

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();
}

编译

 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 warningFinished `dev` profile [unoptimized + debuginfo] target(s) in 0.00sRunning `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 闭包

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();
}

编译

 cargo runBlocking waiting for file lock on build directoryCompiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.07sRunning `target/debug/smartPtr`
Here's a vector: [1, 2, 3]

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

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

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

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接收

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

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

use std::sync::Mutex;fn main() {let m = Mutex::new(5);{// m.lock()会阻塞当前线程,获取锁位置let mut num = m.lock().unwrap();*num = 6;// 退出时会自动释放锁}println!("m = {:?}", m);
}

编译及运行

 cargo runCompiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.57sRunning `target/debug/smartPtr`
m = Mutex { data: 6, poisoned: false, .. }

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

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());
}

编译

 cargo runCompiling smartPtr v0.1.0 (/home/wangji/installer/rust/bobo/smartPtr)Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.85sRunning `target/debug/smartPtr`
Result: 10

参考

  • 第16章~创建线程
http://www.lryc.cn/news/483068.html

相关文章:

  • 力扣 最小路径和
  • Scala中的可变Map操作:简单易懂指南 #Scala Map #Scala
  • 【go从零单排】XML序列化和反序列化
  • 在 Oracle Linux 8.9 上安装Oracle Database 23ai 23.5
  • 在 Ubuntu 上安装 `.deb` 软件包有几种方法
  • 一文了解Android本地广播
  • Ingress nginx 公开TCP服务
  • 谷歌浏览器支持的开发者工具详解
  • 【数据结构】汇编 、机器语言 高级语言 简析。
  • 【青牛科技】GC3901,强势替代 A3901/ALLEGRO应用于摇头机等产品中
  • Java API类与接口:类的转换方法与正则表达式
  • OceanBase JDBC (Java数据库连接)的概念、分类与兼容性
  • Linux服务器定时执行jar重启命令
  • 速览!Win11 22H2/23H2 11月更新补丁KB5046633发布!
  • A day a tweet(sixteen)——The better way of search of ChatGPT
  • 【网络】HTTP 协议
  • git push报错 unexpected disconnect while reading sideband packet
  • JSX 语法与基础组件使用
  • ReactPress:构建高效、灵活、可扩展的开源发布平台
  • emulator总结
  • 【Docker】‘docker‘ 不是内部或外部命令,也不是可运行的程序 或 批处理文件
  • Mysql高可用架构方案
  • Go,15岁了[译]
  • 【大数据学习 | kafka高级部分】kafka的数据同步和数据均衡
  • 微擎框架php7.4使用phpexcel导出数据报错修复
  • Netty实现WebSocket Server是否开启压缩深度分析
  • 【Xrdp联机Ubuntu20.04实用知识点补充】
  • 【电脑】解决DiskGenius调整分区大小时报错“文件使用的簇被标记为空闲或与其它文件有交叉”
  • IDC机房服务器托管的费用组成
  • Halcon深度学习网络模型简介