前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【crossbeam系列】4 crossbeam-channel:加强版channel

【crossbeam系列】4 crossbeam-channel:加强版channel

作者头像
MikeLoveRust
发布于 2020-09-23 07:11:44
发布于 2020-09-23 07:11:44
3K00
代码可运行
举报
运行总次数:0
代码可运行

这一期的内容会轻松一些,讲讲crossbeam中的channel。可是有人就要问了在标准库里面已经有了std::sync::mpsc,为什么crossbeam又要搞出一套channel呢?首先我们来看看标准库中的channel有哪些不足吧

标准库中channel的不足

  1. Receiver不能被clone,是MPSC的channel。理想状况我们希望能有MPMC的channel
  2. Sender和Receiver不是Sync
  3. 在Go语言中,channel一般和select语句一起使用,但是标准库中的channel并不支持select
  4. 有限容量(Bounded)的channel内部实现就是一个简单的Mutex<VecDeque<T>>,性能比Go语言的channel还差
  5. 有Sender(=Unbouded)和SyncSender(=Bounded)的区分,用起来不统一。

crossbeam中加强版的channel

首先,无论容量是否有限,Sender类型统一成一种,这样用起来就很方便。其次对有限容量的channel进行了重写(还记得上一期我们讲的Deque其实就是为了消除Mutex<VecDeque<T>>产生的瓶颈么,这里也类似。对于1-3点:(在此之前我们先简单讲下如何创建crossbeam的channel)

创建channel

有限容量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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();

无限容量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
use crossbeam_channel::unbounded;

// 创建一个无限容量的channel
let (s, r) = unbounded();

// 不会阻塞
for i in 0..1000 {
    s.send(i).unwrap();
}

·

1 支持MPMC

现在终于不用笨拙地给Receiver端加锁了~

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

所以现在可以把引用在线程间传递了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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分支处理超时等逻辑

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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,敬请期待。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rust语言学习交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Rust中channel的使用
Rust的channel是一种用于在不同线程间传递信息的通信机制,它实现了线程间的消息传递。
fliter
2024/03/07
3540
Rust中channel的使用
【翻译】从头实现Rust异步执行器
原文:https://stjepang.github.io/2020/01/31/build-your-own-executor.html 现在我们已经构建了block_on函数,是时候进一步将其转换为一个真正的执行器了。我们希望我们的遗执行器不只是一次运行一个future,而是同时运行多个future!
MikeLoveRust
2020/07/23
9250
【crossbeam系列】5 crossbeam-util和crossbeam-queue:一些实用的小东西
这一次我们来介绍一下crossbeam-util和crossbeam-queue,中的一些东西和用法。
MikeLoveRust
2020/10/23
9770
透过 Rust 探索系统的本原:并发原语
几周前我写了篇关于并发的文章(透过 rust 探索系统的本原:并发篇),从使用者的角度介绍了常用的处理并发的工具:Mutex / RwLock / Channel,以及 async/await。今天我们讲讲这些并发手段背后的原语。这些原语,大家在操作系统课程时大多学过,但如果不是做一些底层的开发,估计大家都不记得了。今天,我们就来简单聊聊这些基础的并发原语,了解它们的差异,明白它们使用的场景,对撰写高性能的并发应用有很大的帮助。
tyrchen
2021/04/07
1.2K0
透过 Rust 探索系统的本原:并发原语
Rust入坑指南:齐头并进(下)
前文中我们聊了Rust如何管理线程以及如何利用Rust中的锁进行编程。今天我们继续学习并发编程。
Jackeyzhe
2020/03/25
8760
【Rust 基础篇】Rust 通道(Channel)
在 Rust 中,通道(Channel)是一种用于在多个线程之间传递数据的并发原语。通道提供了一种安全且高效的方式,允许线程之间进行通信和同步。本篇博客将详细介绍 Rust 中通道的使用方法,包含代码示例和对定义的详细解释。
繁依Fanyi
2023/10/12
4250
【Rust日报】 2019-10-29 async-std v0.99.11 发布
支持 2D 以及 3D 的流体模拟。提供多种类型的流体模拟,并且可以和 nphysics 引擎配合使用。了解更多
MikeLoveRust
2019/10/31
5760
Rust并发控制之Channel
Rust 官方sync包中提供了mpsc模式的 (多生产者,单消费者:multi-producer, single-consumer) channel,可以实现基于消息并发控制,而不是依赖控制内存共享(加锁)。这正是 go 语言作者 R. Pike 所推崇的方式:
newbmiao
2023/12/13
3640
Rust并发控制之Channel
【Rust 日报】2021-03-25 linux-next的rust-next分支被合并了!
Github: https://github.com/zesterer/flume
MikeLoveRust
2021/04/22
6830
【Rust 日报】2022-10-23 tachyonix:一个高性能异步计算框架
这个库是 Asynchronix 的一个分支,它持续努力地构建用于系统仿真的高性能异步计算框架。
MikeLoveRust
2022/11/28
3820
Rust异步编程之Future并发处理
上篇文章我们知道,Rust的Future是异步执行,await时是阻塞在当前的异步任务task上,直到完成。
newbmiao
2024/01/11
5300
Rust异步编程之Future并发处理
Rust 中的 QUIC 实现 --- quinn
QUIC 是基于 UDP 的多路复用、安全传输协议。可以简单理解为在用户空间将 TCP 里的机制实现了一遍,比如拥塞控制、流量控制等。好处是升级比较方便,TCP 协议栈是内核中实现的,只能随内核升级,而 QUIC 可灵活升级。
谛听
2022/01/30
4.2K0
rust的并发编程
并发的方式 多进程 多线程 协程 多线程遇到的问题 数据竞争 内存不安全和未定义的行为 常用的两种线程模型(rust都支持) 锁管理临界区 消息通信 rust的并发 通过后thread::spawn关键字 自定义线程通过Builder::new 线程从并发模型 数据共享 Rrc实现变量-可以读,但是没法修改 互斥mutex。 arc和mutex。共享变量 支持读写锁RwLock 通过消息通信 mpse模块 channel和sync_channel rust中的线程安全 parking_lot检查死锁 保证安
李子健
2022/05/14
4440
【Rust 基础篇】Rust 通道实现单个消费者多个生产者模式
在 Rust 中,我们可以使用通道(Channel)来实现单个消费者多个生产者模式,简称为 MPMC。MPMC 是一种常见的并发模式,适用于多个线程同时向一个通道发送数据,而另一个线程从通道中消费数据的场景。本篇博客将详细介绍 Rust 中单个消费者多个生产者模式的实现方法,包含代码示例和对定义的详细解释。
繁依Fanyi
2023/10/12
5560
C 和 Java 没那么香了,Serverless 时代 Rust 即将称王?
作者 | 马超       责编 | 张红月 出品 | CSDN博客 Serverless的核心理念就是函数式计算,开发者无须再关注具体的模块,云上部署的粒度变成了程序函数,自动伸缩、扩容等工作完全由云服务负责。 Serverless Computing,即”无服务器计算”,其实这一概念在刚刚提出的时候并没有获得太多的关注,直到2014年AWS Lambda这一里程碑式的产品出现。Serverless算是正式走进了云计算的舞台。2018年5月,Google在KubeCon+CloudNative 201
博文视点Broadview
2023/05/06
2490
C 和 Java 没那么香了,Serverless 时代 Rust 即将称王?
听GPT 讲Rust源代码--library/std(16)
题图来自 EVALUATION OF RUST USAGE IN SPACE APPLICATIONS BY DEVELOPING BSP AND RTOS TARGETING SAMV71[1]
fliter
2023/11/08
3480
听GPT 讲Rust源代码--library/std(16)
透过 rust 探索系统的本原:并发篇
rust 是一门非常优秀的语言,我虽然没有特别正式介绍过 rust 本身,但其实已经写了好多篇跟 rust 相关的文章:
tyrchen
2021/03/17
9800
透过 rust 探索系统的本原:并发篇
【翻译】200行代码讲透RUST FUTURES (7)
我们将用一个伪reactor和一个简单的执行器创建我们自己的Futures,它允许你在浏览器中编辑和运行代码
MikeLoveRust
2020/08/05
1.3K0
解锁!玩转 HelloGitHub 的新姿势
本文不会涉及太多技术细节和源码,请放心食用 大家好,我是 HelloGitHub 的老荀,好久不见啊! 我在完成 HelloZooKeeper 系列之后,就很少“露面了”。但是我对开源和 HelloGitHub 的热情并没有丝毫的减少。这不,逮着个机会就来输出一波,防止被大家遗忘😂。 这次带来的是我写的一款在终端浏览 HelloGitHub 的工具:hg-tui,让你双手不离开键盘就能畅游在 HG 的开源世界。功能如下: 色彩丰富、平铺展示 关键字搜索月刊往期的项目 类 Vim 的快捷键操作方式
HelloGitHub
2022/09/26
4890
Rust Druid 之Selector选择器使用
Druid 内部也是基于事件循环的,当程序调用 AppLauncher::launch() 方法时,程序进入事件循环。在事件循环中,窗体间的消息传递是使用Selector来进行。
8菠萝
2021/05/24
1.1K0
相关推荐
Rust中channel的使用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验