【crossbeam系列】4 crossbeam-channel:加强版channel
时间:2022-07-25
本文章向大家介绍【crossbeam系列】4 crossbeam-channel:加强版channel,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
这一期的内容会轻松一些,讲讲crossbeam中的channel。可是有人就要问了在标准库里面已经有了std::sync::mpsc
,为什么crossbeam又要搞出一套channel呢?首先我们来看看标准库中的channel有哪些不足吧
标准库中channel的不足
- Receiver不能被clone,是MPSC的channel。理想状况我们希望能有MPMC的channel
- Sender和Receiver不是
Sync
。 - 在Go语言中,channel一般和
select
语句一起使用,但是标准库中的channel并不支持select - 有限容量(Bounded)的channel内部实现就是一个简单的
Mutex<VecDeque<T>>
,性能比Go语言的channel还差 - 有Sender(=Unbouded)和SyncSender(=Bounded)的区分,用起来不统一。
crossbeam中加强版的channel
首先,无论容量是否有限,Sender类型统一成一种,这样用起来就很方便。其次对有限容量的channel进行了重写(还记得上一期我们讲的Deque其实就是为了消除Mutex<VecDeque<T>>
产生的瓶颈么,这里也类似。对于1-3点:(在此之前我们先简单讲下如何创建crossbeam的channel)
创建channel
有限容量
use crossbeam_channel::bounded;
// 创建一个容量是5的channel
let (s, r) = bounded(5);
// 5条消息之内都不会阻塞
for i in 0..5 {
s.send(i).unwrap();
}
// 超过5条就会阻塞了
// s.send(5).unwrap();
无限容量
use crossbeam_channel::unbounded;
// 创建一个无限容量的channel
let (s, r) = unbounded();
// 不会阻塞
for i in 0..1000 {
s.send(i).unwrap();
}
·
1 支持MPMC
现在终于不用笨拙地给Receiver端加锁了~
use std::thread;
use crossbeam_channel::bounded;
let (s1, r1) = bounded(0);
let (s2, r2) = (s1.clone(), r1.clone());
// 起一个线程先接受一个消息然后发出一个消息
thread::spawn(move || {
r2.recv().unwrap();
s2.send(2).unwrap();
});
// 发送一个消息然后接受一个消息
s1.send(1).unwrap();
r1.recv().unwrap();
2 Sender和Receiver是Sync
所以现在可以把引用在线程间传递了
use std::thread;
use crossbeam_channel::bounded;
use crossbeam_utils::thread::scope;
let (s, r) = bounded(0);
scope(|scope| {
// 起一个线程先接受一个消息然后发出一个消息
scope.spawn(|_| {
r.recv().unwrap();
s.send(2).unwrap();
});
// 发送一个消息然后接受一个消息
s.send(1).unwrap();
r.recv().unwrap();
}).unwrap();
3 支持select
提供了类似Go语言功能的select
宏,支持使用default
分支处理超时等逻辑
use std::thread;
use std::time::Duration;
use crossbeam_channel::unbounded;
let (s1, r1) = unbounded();
let (s2, r2) = unbounded();
thread::spawn(move || s1.send(10).unwrap());
thread::spawn(move || s2.send(20).unwrap());
select! {
recv(r1) -> msg => assert_eq!(msg, Ok(10)),
recv(r2) -> msg => assert_eq!(msg, Ok(20)),
default(Duration::from_secs(1)) => println!("timed out"),
}
并且其实select内部不仅仅支持接受消息,也支持发送消息。同时还有更高级的动态select支持~
小结
我们看到,crossbeam的channel优雅的解决了标准库中上述的5个问题,看来没事可以多用用了~下一期我们会讲一下crossbeam-util和crossbeam-queue,敬请期待。
- 初识javascript
- [原创]x.509证书在WCF中的应用(Web/IIS篇)
- Javascript之Dom学习
- 考试备战系列--软考--01基础架构概念
- HTML技术简介
- 记一次非常愉悦的 Python 使用经历
- Jquery 触发器之treigger()方法简介
- 如何节省 1TB 图片带宽?解密极致图像压缩
- Redis快速入门
- 王者荣耀未来新版本的环境优化计划,人工智能技术将引入
- Jquery遍历数组之$.inArray()方法介绍
- [原创图解]Win2003证书服务配置/客户端(服务端)证书申请/IIS站点SSL设置
- JavaScript之firstChild属性、lastChild属性、nodeValue属性学习
- JavaScript之获取和设置元素属性
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP simplexml_import_dom()函数讲解
- PHP getName()函数讲解
- Laravel框架集成UEditor编辑器的方法图文与实例详解
- PHP+redis实现的购物车单例类示例
- ThinkPHP3.2.3框架邮件发送功能图文实例详解
- PHP simplexml_load_file()函数讲解
- Python下划线5种含义代码实例解析
- PHP getDocNamespaces()函数讲解
- Django实现内容缓存实例方法
- Tensorflow–取tensorf指定列的操作方式
- spring-boot-route(一)Controller接收参数的几种方式
- python中 _、__、__xx__()区别及使用场景
- 浅谈TensorFlow中读取图像数据的三种方式
- python 最简单的实现适配器设计模式的示例
- spring-boot-route(二):读取配置文件的几种方式