得益于所有权系统以及类型系统,Rust有着非常优异的并发性能。

1. 线程的基本应用

创建线程:

use std::thread;
use std::time::Duration;
fn main() {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));}
}
hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 2 from the main thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 4 from the main thread!
hi number 5 from the spawned thread!

需要注意的是,当主线程结束,不管thread::spawn创建的子线程是否执行完毕,程序都会结束。所以子线程的print语句只执行到了i=5。

使用Join()让主线程等待子线程执行完毕:

如果我们想让子线程执行完毕,可以将thread::spawn赋给变量,然后调用join。在rust中,thread::spawn返回的type是JoinHandle。

use std::thread;
use std::time::Duration;
fn main() {//thread::spawn创建线程后返回JoinHandle 类型给handlelet 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));}//调用join,让主线程等待至子线程执行完毕//unwrap的作用:请求返回结果,如果报错就会panic并停止程序handle.join().unwrap();
}
hi number 1 from the main thread!
hi number 2 from the main thread!
hi number 1 from the spawned thread!
hi number 3 from the main thread!
hi number 2 from the spawned thread!
hi number 4 from the main thread!
hi number 3 from the spawned 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让线程获得变量所有权

在Rust里,当闭包函数使用外界环境的变量时,编译器会推断闭包函数该采用借用,还是获取变量所有权的方式。当创建的子线程需要使用主线程的数据时,由于闭包函数运行子线程环境中而无法确定借用是否一直有效,所以需要使用move来使变量所有权移交至子线程的闭包函数。

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

2. 线程通信机制:channel,transmitter与receiver

Rust book中将rust的线程通信的channel比作一条河,数据比作橡皮鸭。橡皮鸭从上游(transmitter)顺流而下到下游(receiver)。Rust中实现线程通信的标准库为mpsc,是multiple producer; single consumer的缩写。意思是在rust线程通信机制中,可以有多个数据发送端,然后像河流汇聚到大海一般,最终由一个接受端接收。

use std::thread;
use std::sync::mpsc;
fn main() {//创建channel//mpsc::channel()返回一个tuple,包含transmitter:tx , receiver:rx//在很多领域tx,rx都被当做是transmitter与receiver的缩写//所以rust book的这个例子也以此来命名let (tx, rx) = mpsc::channel();thread::spawn(move || {let val = String::from("hi");//transmitter从子线程发送数据tx.send(val).unwrap();//需要注意的是,此时val的所有权也被移交给了数据的接收线程});//主线程接受子线程数据let received = rx.recv().unwrap();println!("Got: {}", received);
}
Got: hi

Sending Multiple Values and Seeing the Receiver Waiting:

为了直观展现出两个线程通过channel保持communicating,对上述代码做出一点修改:使用for循环发送多条value,并且每次发送间隔1秒。同样也以for循环在主线程中接收数据,这时rx被当作一个iterator。每当接收到一条数据,for循环就会执行一次。直到数据发送完毕,channel关闭。

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

应该可以直观的看到每条数据之间都间隔了1秒。

Got: hi
Got: from
Got: the
Got: thread

使用clone函数实现mpsc: multiple producer; single consumer

use std::thread;
use std::sync::mpsc;
use std::time::Duration;
fn main() {let (tx, rx) = mpsc::channel();//使用clone函数clone一个transmitterlet tx1 = mpsc::Sender::clone(&tx);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));}});thread::spawn(move || {let vals = vec![String::from("more"),String::from("messages"),String::from("for"),String::from("you"),];for val in vals {tx1.send(val).unwrap();thread::sleep(Duration::from_secs(1));}});for received in rx {println!("Got: {}", received);}
}
Got: hi
Got: more
Got: from
Got: messages
Got: the
Got: for
Got: you
Got: thread

Rust:并发编程(concurrent programming)相关推荐

  1. 并发编程 – Concurrent 用户指南

    转载自 并发编程 – Concurrent 用户指南 1. java.util.concurrent – Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.c ...

  2. 并发编程-concurrent指南-原子操作类-AtomicInteger

    在java并发编程中,会出现++,--等操作,但是这些不是原子性操作,这在线程安全上面就会出现相应的问题.因此java提供了相应类的原子性操作类. 1.AtomicInteger 可以用原子方式更新的 ...

  3. 并发编程 – Concurrent 用户指南( 下 )

    16. 执行器服务 ExecutorService java.util.concurrent.ExecutorService 接口表示一个异步执行机制,使我们能够在后台执行任务.因此一个 Execut ...

  4. 并发编程-concurrent指南-阻塞队列BlockingQueue

    阻塞队列BlockingQueue,java.util.concurrent下的BlockingQueue接口表示一个线程放入和提取实例的队列. 适用场景: BlockingQueue通常用于一个线程 ...

  5. 并发编程-concurrent指南-原子操作类-AtomicBoolean

    类AtomicBoolean 可以用原子方式更新的 boolean 值.有关原子变量属性的描述,请参阅 java.util.concurrent.atomic 包规范.AtomicBoolean 可用 ...

  6. 并发编程-concurrent指南-线程池ExecutorService的使用

    有几种不同的方式来将任务委托给 ExecutorService 去执行: execute(Runnable) submit(Runnable) submit(Callable) invokeAny(- ...

  7. rust异步编程--理解并发/多线程/回调/异步/future/promise/async/await/tokio

    1. 异步编程简介 通常我们将消息通信分成同步和异步两种: 同步就是消息的发送方要等待消息返回才能继续处理其它事情 异步就是消息的发送方不需要等待消息返回就可以处理其它事情 很显然异步允许我们同时做更 ...

  8. Erlang并发编程思想

    文章目录 Erlang的并发概念 Erlang程序反映了我们思考和交流和方式. 人类表现为独立的个体,通过发送消息进行交流. 如果有人死亡,其他人会注意到. register(AnAtom,Pid) ...

  9. Java并发编程-并发工具包(java.util.concurrent)使用指南(全)

    1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.concurrent 包.这个包包含有一系列能够让 Ja ...

  10. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自 Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mul ...

最新文章

  1. 微信小程序学习Course 8 本地缓存API
  2. 无监督方法实现C++、Java、Python 代码转换,程序员:出了bug怎么办,两种语言都要看吗?...
  3. 使用Spring2.5的Autowired实现注释型的IOC(转载)
  4. python学习笔记(六)——函数的作用域和装饰器
  5. lixuxmint系统定制与配置(4)-应用安装
  6. python实现快速创建订单_从销售订单和Od中的产品订单创建新记录
  7. angular 内容投影
  8. 那个傻子的网站突然打不开虚拟光驱
  9. 反射工厂在数据访问层的应用
  10. python 知乎 合并 pdf_32.使用selenium爬取知乎,并实现多页保存为一个PDF文件
  11. 【原创】Nginx+PHP-FPM优化技巧总结
  12. 虚拟助手之争,智能音箱能否挑战智能手机?
  13. Vista v12.0 Win32-ISO 1DVD(地震数据处理)
  14. 计算机电路基础第三版清华大学出版社答案,清华大学出版社-图书详情-《计算机电路基础(第2版)》...
  15. 腾讯笔试题 微信红包
  16. 利用计算机技术分析学生成绩,基于数据挖掘技术的学生成绩分析
  17. 无损音乐下载器 Delphi版
  18. WPS WORD 项目符号和编号,继续前一列表
  19. PL330 DMAC笔记(1) - 简介
  20. 闲聊HTML5的新特性

热门文章

  1. c语言实例--十进制转化为二进制
  2. GarsiaWachs算法
  3. sklearn 学习之 model_selection
  4. 最近一直在想如何才能把我的想法变成现实
  5. Google Earth Engine(GEE)最全632个数据集在哪里找?文章末含名称!
  6. iTab新标签页,一款个性化的浏览器起始页插件
  7. 机器人三大定律的发展和演进概述
  8. mysql sql dateadd函数_SQL DATEADD函数 (sqlserver 只更新表中年份,不改其他时间)...
  9. 亲身经历灵魂附体与出马仙之说
  10. 用表格完成个人信息网页的设计 基本信息:姓名,学号,出生日期,手机号码,证件类型,证件号码,学校,学院,专业,学制,入学时间,个人证件图像兴趣爱好