企业网站优化做法,权重网站建设,怎么一键打开wordpress,亚马逊主机wordpress1.共享状态并发
虽然消息传递是一个很好的处理并发的方式#xff0c;但并不是唯一一个。另一种方式是让多个线程拥有相同的共享数据。在学习Go语言编程过程中大家应该听到过一句口号:不要通过共享内存来通讯。
在某种程度上#xff0c;任何编程语言中的信道都类…1.共享状态并发
虽然消息传递是一个很好的处理并发的方式但并不是唯一一个。另一种方式是让多个线程拥有相同的共享数据。在学习Go语言编程过程中大家应该听到过一句口号:不要通过共享内存来通讯。
在某种程度上任何编程语言中的信道都类似于单所有权因为一旦将一个值传送到信道中将无法再使用这个值。共享内存类似于多所有权多个线程可以同时访问相同的内存位置。第十五章介绍了智能指针如何使得多所有权成为可能然而这会增加额外的复杂性因为需要以某种方式管理这些不同的所有者。Rust 的类型系统和所有权规则极大的协助了正确地管理这些所有权。作为一个例子让我们看看互斥器一个更为常见的共享内存并发原语。
互斥器mutex是 mutual exclusion 的缩写也就是说任意时刻其只允许一个线程访问某些数据。为了访问互斥器中的数据线程首先需要通过获取互斥器的 锁lock来表明其希望访问数据。锁是一个作为互斥器一部分的数据结构它记录谁有数据的排他访问权。因此我们描述互斥器为通过锁系统 保护guarding其数据。
互斥器以难以使用著称因为你不得不记住 在使用数据之前尝试获取锁。 处理完被互斥器所保护的数据之后必须解锁数据这样其他线程才能够获取锁。
作为一个现实中互斥器的例子想象一下在某个会议的一次小组座谈会中只有一个麦克风。如果一位成员要发言他必须请求或表示希望使用麦克风。一旦得到了麦克风他可以畅所欲言然后将麦克风交给下一位希望讲话的成员。如果一位成员结束发言后忘记将麦克风交还其他人将无法发言。如果对共享麦克风的管理出现了问题座谈会将无法如期进行
正确的管理互斥器异常复杂这也是许多人之所以热衷于信道的原因。然而在 Rust 中得益于类型系统和所有权我们不会在锁和解锁上出错。
2.MutexT的API
作为展示如何使用互斥器的例子让我们从在单线程上下文使用互斥器开始, 看下面的代码:
use std::sync::Mutex;fn main() {let m Mutex::new(5);{let mut num m.lock().unwrap();*num 6;}println!(m {:?}, m);
}
像很多类型一样我们使用关联函数 new 来创建一个 MutexT。使用 lock 方法获取锁以访问互斥器中的数据。这个调用会阻塞当前线程直到我们拥有锁为止。
如果另一个线程拥有锁并且那个线程 panic 了则 lock 调用会失败。在这种情况下没人能够再获取锁所以这里选择 unwrap 并在遇到这种情况时使线程 panic。
一旦获取了锁就可以将返回值在这里是num视为一个其内部数据的可变引用了。类型系统确保了我们在使用 m 中的值之前获取锁。m 的类型是 Mutexi32 而不是 i32所以 必须 获取锁才能使用这个 i32 值。我们是不会忘记这么做的因为反之类型系统不允许访问内部的 i32 值。
MutexT 是一个智能指针。更准确的说lock 调用 返回 一个叫做 MutexGuard 的智能指针。这个智能指针实现了 Deref 来指向其内部数据其也提供了一个 Drop 实现当 MutexGuard 离开作用域时自动释放锁为此我们不会忘记释放锁并阻塞互斥器为其它线程所用的风险因为锁的释放是自动发生的。
丢弃了锁之后可以打印出互斥器的值并发现能够将其内部的 i32 改为 6。
3.在线程间共享MutexT
现在让我们尝试使用 MutexT 在多个线程间共享值。我们将启动十个线程并在各个线程中对同一个计数器值加一这样计数器将从 0 变为 10。看下面的代码:
use std::sync::Mutex;
use std::thread;fn main() {let counter Mutex::new(0);let mut handles vec![];for _ in 0..10 {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());
}
这里创建了一个 counter 变量来存放内含 i32 的 MutexT, 接下来遍历 range 创建了 10 个线程。使用了 thread::spawn 并对所有线程使用了相同的闭包它们每一个都将调用 lock 方法来获取 MutexT 上的锁接着将互斥器中的值加一。当一个线程结束执行num 会离开闭包作用域并释放锁这样另一个线程就可以获取它了。
在主线程中我们收集了所有的 join 句柄, 调用它们的 join 方法来确保所有线程都会结束。这时主线程会获取锁并打印出程序的结果。
编译上面的代码, Rust编译器报了一个错误: 错误信息表明 counter 值在上一次循环中被移动了。所以 Rust 告诉我们不能将 counter 锁的所有权移动到多个线程中。下面来看看如何修复这个错误。
4.多线程和多所有权
我们先尝试将MutexT封装进RcT中并在将所有权移入线程之前克隆RcT,看下面代码:
use std::rc::Rc;
use std::sync::Mutex;
use std::thread;fn main() {let counter Rc::new(Mutex::new(0));let mut handles vec![];for _ 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());
}
再一次编译代码,纳尼, 居然又报了另一个错误, 成年人的崩溃谁能懂: RcMutexi32 cannot be sent between threads safely。这个错误编译器告诉我们原因是:the trait Send is not implemented for RcMutexi32。
RcT 并不能安全的在线程间共享。当 RcT 管理引用计数时它必须在每一个 clone 调用时增加计数并在每一个克隆被丢弃时减少计数。RcT 并没有使用任何并发原语来确保改变计数的操作不会被其他线程打断。在计数出错时可能会导致诡异的 bug比如可能会造成内存泄漏或在使用结束之前就丢弃一个值。我们所需要的是一个完全类似 RcT又以一种线程安全的方式改变引用计数的类型。
5.原子引用计数ArcT
在Rust标准库中, 提供了一个名为ArcT的类型, 这是一个可以安全的用于并发环境的类型, 字母 “a” 代表 原子性atomic所以这是一个 原子引用计数atomically reference counted类型, 将代码修改为:
use std::sync::{Arc, Mutex};
use std::thread;fn main() {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();}println!(Result: {}, *counter.lock().unwrap());
}
再次编译代码, 执行结果如下: 这次终于得到结果10, 程序从0数到10, 虽然过程看上去并不明显, 但我们却学到了很多关于MutexT和线程安全的内容。 文章转载自: http://www.morning.dktyc.cn.gov.cn.dktyc.cn http://www.morning.hmnhp.cn.gov.cn.hmnhp.cn http://www.morning.rpth.cn.gov.cn.rpth.cn http://www.morning.eronghe.com.gov.cn.eronghe.com http://www.morning.lqjpb.cn.gov.cn.lqjpb.cn http://www.morning.cmdfh.cn.gov.cn.cmdfh.cn http://www.morning.ckxd.cn.gov.cn.ckxd.cn http://www.morning.jfxth.cn.gov.cn.jfxth.cn http://www.morning.kdnrc.cn.gov.cn.kdnrc.cn http://www.morning.qnwyf.cn.gov.cn.qnwyf.cn http://www.morning.rdtq.cn.gov.cn.rdtq.cn http://www.morning.ghslr.cn.gov.cn.ghslr.cn http://www.morning.lzqxb.cn.gov.cn.lzqxb.cn http://www.morning.tbstj.cn.gov.cn.tbstj.cn http://www.morning.w58hje.cn.gov.cn.w58hje.cn http://www.morning.whclz.cn.gov.cn.whclz.cn http://www.morning.mgnrc.cn.gov.cn.mgnrc.cn http://www.morning.rwqj.cn.gov.cn.rwqj.cn http://www.morning.ymfzd.cn.gov.cn.ymfzd.cn http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.zmyzt.cn.gov.cn.zmyzt.cn http://www.morning.dwzwm.cn.gov.cn.dwzwm.cn http://www.morning.rfljb.cn.gov.cn.rfljb.cn http://www.morning.wkmyt.cn.gov.cn.wkmyt.cn http://www.morning.yrxcn.cn.gov.cn.yrxcn.cn http://www.morning.knmp.cn.gov.cn.knmp.cn http://www.morning.mmtbn.cn.gov.cn.mmtbn.cn http://www.morning.tfzjl.cn.gov.cn.tfzjl.cn http://www.morning.cknws.cn.gov.cn.cknws.cn http://www.morning.nqwkn.cn.gov.cn.nqwkn.cn http://www.morning.rqzyz.cn.gov.cn.rqzyz.cn http://www.morning.prhqn.cn.gov.cn.prhqn.cn http://www.morning.rcqyk.cn.gov.cn.rcqyk.cn http://www.morning.zbkdm.cn.gov.cn.zbkdm.cn http://www.morning.litao4.cn.gov.cn.litao4.cn http://www.morning.nkpml.cn.gov.cn.nkpml.cn http://www.morning.plkrl.cn.gov.cn.plkrl.cn http://www.morning.dwztj.cn.gov.cn.dwztj.cn http://www.morning.xxwl1.com.gov.cn.xxwl1.com http://www.morning.pxlsh.cn.gov.cn.pxlsh.cn http://www.morning.bybhj.cn.gov.cn.bybhj.cn http://www.morning.pphbn.cn.gov.cn.pphbn.cn http://www.morning.nnjq.cn.gov.cn.nnjq.cn http://www.morning.rwpjq.cn.gov.cn.rwpjq.cn http://www.morning.ddzqx.cn.gov.cn.ddzqx.cn http://www.morning.dkbgg.cn.gov.cn.dkbgg.cn http://www.morning.fxjnn.cn.gov.cn.fxjnn.cn http://www.morning.wdhzk.cn.gov.cn.wdhzk.cn http://www.morning.rfbq.cn.gov.cn.rfbq.cn http://www.morning.wffxr.cn.gov.cn.wffxr.cn http://www.morning.mwmtk.cn.gov.cn.mwmtk.cn http://www.morning.zcckq.cn.gov.cn.zcckq.cn http://www.morning.fthqc.cn.gov.cn.fthqc.cn http://www.morning.nkpml.cn.gov.cn.nkpml.cn http://www.morning.lxqkt.cn.gov.cn.lxqkt.cn http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn http://www.morning.mgtrc.cn.gov.cn.mgtrc.cn http://www.morning.ysjjr.cn.gov.cn.ysjjr.cn http://www.morning.dtmjn.cn.gov.cn.dtmjn.cn http://www.morning.bpmnl.cn.gov.cn.bpmnl.cn http://www.morning.wckrl.cn.gov.cn.wckrl.cn http://www.morning.hbqhz.cn.gov.cn.hbqhz.cn http://www.morning.litao4.cn.gov.cn.litao4.cn http://www.morning.jzykw.cn.gov.cn.jzykw.cn http://www.morning.mmjqk.cn.gov.cn.mmjqk.cn http://www.morning.wrtbx.cn.gov.cn.wrtbx.cn http://www.morning.bmtkp.cn.gov.cn.bmtkp.cn http://www.morning.cnyqj.cn.gov.cn.cnyqj.cn http://www.morning.sooong.com.gov.cn.sooong.com http://www.morning.sjwzz.cn.gov.cn.sjwzz.cn http://www.morning.psdbf.cn.gov.cn.psdbf.cn http://www.morning.pttrs.cn.gov.cn.pttrs.cn http://www.morning.qtyfb.cn.gov.cn.qtyfb.cn http://www.morning.xznrk.cn.gov.cn.xznrk.cn http://www.morning.dhnqt.cn.gov.cn.dhnqt.cn http://www.morning.lznqb.cn.gov.cn.lznqb.cn http://www.morning.nytpt.cn.gov.cn.nytpt.cn http://www.morning.nwynx.cn.gov.cn.nwynx.cn http://www.morning.qdsmile.cn.gov.cn.qdsmile.cn http://www.morning.pcrzf.cn.gov.cn.pcrzf.cn