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

北京知名网站建设58招商加盟项目

北京知名网站建设,58招商加盟项目,阿里云虚拟主机可以做几个网站,网站工程是干啥的Rust 标准库只提供了 1:1 线程模型 Rust 是较为底层的语言,如果愿意牺牲性能来换取抽象,以获得对线程运行更精细的控制及更低的上下文切换成本,使用实现了 M:N 线程模型的 crate 示例 use std::thread; use std::time::Duration;fn main() …

Rust 标准库只提供了 1:1 线程模型
Rust 是较为底层的语言,如果愿意牺牲性能来换取抽象,以获得对线程运行更精细的控制及更低的上下文切换成本,使用实现了 M:N 线程模型的 crate

示例

use std::thread;
use std::time::Duration;fn main() {// 调用 thread::spawn 函数并传递一个闭包,来创建线程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));}// 等待结束// // `unwrap` 在接收到 `None` 时将返回 `panic`handle.join().unwrap();
}

在一个线程中使用另一个线程的数据

在参数列表前使用 move 关键字强制闭包获取其使用的环境值的所有权。
这个技巧在创建新线程将值的所有权从一个线程移动到另一个线程时最为实用

use std::thread;fn main() {let v = vec![1, 2, 3]let handle = thread::spawn(|| {// `v` is borrowed here// Rust 不知道这个新建线程会执行多久,所以无法知晓 v 的引用是否一直有效println!("Here's a vector: {:?}", v);});// 一个具有闭包的线程,尝试使用一个在主线程中被回收的引用 v// drop(v);handle.join().unwrap();
}

force the closure to take ownership of v (and any other referenced variables), use the move keyword

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();// value borrowed here after moveprintln!("Here's a vector: {:?}", v); // 这里编译报错
}
use std::thread;fn main() {let v = vec![1, 2, 3]let handle = thread::spawn(move || {// `v` is borrowed hereprintln!("Here's a vector: {:?}", v);});handle.join().unwrap();
}

channel

mpsc:multiple producer, single consumer

基本用法

use std::thread;
// 多发单收模型
// multiple producer, single consumer
use std::sync::mpsc;fn main() {// tx 是发送端,rx是接收端let (tx, rx) = mpsc::channel();thread::spawn(move || {let val = String::from("hi");tx.send(val).unwrap();});// 主线程阻塞let received = rx.recv().unwrap();println!("Got: {}", received);
}

try_recv 不会阻塞,相反它立刻返回一个 Result<T, E>:Ok 值包含可用的信息,而 Err 值代表此时没有任何消息

示例

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

所有权被转移

use std::thread;
use std::sync::mpsc;fn main() {let (tx, rx) = mpsc::channel();thread::spawn(move || {let val = String::from("hi");tx.send(val).unwrap();// 编译失败//  value borrowed here after moveprintln!("val is {}", val);});let received = rx.recv().unwrap();println!("Got: {}", received);
}

多生产者

通过克隆通道的发送端来做到
类似于Go中的:“不要通过共享内存来通讯;而是通过通讯来共享内存
(“Do not communicate by sharing memory; instead, share memory by communicating.”)

use std::thread;
use std::sync::mpsc;
use std::time::Duration;fn main() {let (tx, rx) = mpsc::channel();let tx1 = tx.clone();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);}println!("finish")
}

Mutex 互斥器

使用方式

cat main.rs
use std::sync::Mutex;fn main() {let m = Mutex::new(5);{// lock 调用 返回 一个叫做 MutexGuard 的智能指针// 这个智能指针实现了 Deref 来指向其内部数据// 也提供了一个 Drop 实现当 MutexGuard 离开作用域时自动释放锁let mut num = m.lock().unwrap();*num = 6;}// 打印内容如下 Mutex { data: 6, poisoned: false, .. }println!("m = {:?}", m);
}

糟糕例子

use std::sync::Mutex;
use std::thread;fn main() {let counter = Mutex::new(0);let mut handles = vec![];for _ in 0..10 {// value moved into closure here, in previous iteration of loop// 编译失败let handle = thread::spawn(move || {let mut num = counter.lock().unwrap();*num += 1;});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("Result: {}", *counter.lock().unwrap());
}

解决方式-Arc

Arc 和 Rc 有着相同的 API
Arc 一个类似 Rc 并可以安全的用于并发环境的类型
字母 “a” 代表 原子性(atomic),所以这是一个原子引用计数

为什么不是所有标准库中的类型都默认使用 Arc 实现?
线程安全带有性能惩罚,只在必要时才为此买单

use std::sync::{Mutex, Arc};
use std::thread;fn main() {// counter 是不可变的,因为前面没有mut// 意味着Mutex<T> 提供了内部可变性// 就像使用 RefCell<T> 可以改变 Rc<T> 中的内容那样// 使用 Mutex<T> 来改变 Arc<T> 中的内容 let counter = Arc::new(Mutex::new(0));let mut handles = vec![];for _ in 0..10 {let counter = Arc::clone(&counter);let handle = thread::spawn(move || {let mut num = counter.lock().unwrap();*num += 1;});handles.push(handle);}for handle in handles {handle.join().unwrap();}// 打印结果为10println!("Result: {}", *counter.lock().unwrap());
}

Mutex 也有造成 死锁(deadlock) 的风险

使用 Sync 和 Send trait 的可扩展并发

语言本身对并发知之甚少。上述讨论的几乎所有内容都属于标准库,而不是语言本身的内容,可以编写自己的或使用别人编写的并发功能。
但有两个并发概念是内嵌于语言中的:std::marker 中的 Sync 和 Send trait

通过 Send 允许在线程间转移所有权

【Send 标记 trait】
表明类型的所有权可以在线程间传递
几乎所有的 Rust 类型都是Send 的,但是也有例外,比如Rc
如果克隆了 Rc 的值并尝试将克隆的所有权转移到另一个线程,这两个线程都可能同时更新引用计数,Rc 被实现为用于单线程场景,所以不用担心多线程下的引用计数问题。

糟糕例子

the trait Send is not implemented for Rc<Mutex<i32>>

use std::rc::Rc;
use std::sync::Mutex;
use std::thread;fn main() {let counter = Rc::new(Mutex::new(0));let mut handles = vec![];// Rc<Mutex<i32>>` cannot be sent between threads safelyfor _ in 0..10 {let counter = Rc::clone(&counter);let handle = thread::spawn(move || {let mut num = counter.lock().unwrap();*num += 1;});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("Result: {}", *counter.lock().unwrap());
}

解决办法

使用原子引用计数 Arc

Sync 允许多线程访问

【Sync 标记 trait】
一个实现了 Sync 的类型可以安全的在多个线程中拥有其值的引用
对于任意类型 T,如果 &T(T 的引用)是 Send 的话 T 就是 Sync 的
其引用就可以安全的发送到另一个线程

Rc 不是 Sync的
RefCell 和 Cell 系列类型不是 Sync 的
RefCell 在运行时所进行的借用检查也不是线程安全的
Mutex 是 Sync 的,可以被用来在多线程中共享访问

http://www.yayakq.cn/news/863362/

相关文章:

  • 优秀企业网站设计欣赏一个空间怎么放两个网站
  • 长沙网站设计费用屏蔽收索引擎抓取网站
  • 阿里云备案网站备案外贸搜索引擎
  • 重庆网站制作一般需要多少钱凯里网站开发
  • 企业为什么要建立自己的网站小程序变成网页链接
  • 大公司网页设计用什么软件好如何进行搜索引擎优化 简答案
  • 成都建设二维码网站深圳模板网站建设公
  • 建设造价信息网站直播软件app下载免费
  • 企业微网站与手机微信做品牌折扣微信推广的网站
  • 做网站怎样使图片自由移动wordpress怎么修改logo尺寸
  • 网站设计就业中山网站建设找阿 n 2
  • 做网站的出路纯html5网站源码
  • 网投网站制作上海优化网站公司哪家好
  • 深圳网站建设网络公司wordpress单页主题营销
  • 互助网站制作公司抚州购物网站开发设计
  • 漯河哪个网站推广效果好怎么样才算是一个网站页面
  • 企业网站营销的优缺点及案例南平市建设集团网站
  • 甘肃网站建设推广服务wordpress 增加侧边栏
  • word文档做网站小型企业网站设计教程
  • 网站做业务赚钱吗三种人不适合做程序员
  • 有源码手机怎么搭建网站哪些网站做农产品电子商务
  • 济南建网站送400电话互联网公司加盟
  • 南京网站维护公司有哪些苏州新区网站制作公司
  • 咋么做网站百度关键词优化多久上首页
  • 网络上如何推广网站更换dns能上国外网站吗
  • 网站首页快照应该怎么下拉框关键词软件
  • 商丘网站建设公司白云区建网站设计
  • dede网站建站教程外贸的订单在哪个网站找
  • 手机如何制作网站教程科技小制作一等奖
  • 网站建设类课题的研究方法烟台制作网站的公司