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

2023-05-16

这一期的内容会轻松一些,讲讲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

有限容量

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,敬请期待。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【crossbeam系列】4 crossbeam-channel:加强版channel 的相关文章

随机推荐

  • LINUX 下使用V4L2协议通过MMAP方式进行摄像头原始图像的采集与存储

    原理 Linux内核用一个被称为V4L2的机制来管理摄像头图像信息 在内核中 xff0c 摄像头所捕获的视频数据 xff0c 我们可以通过一个队列来存储 xff0c 当摄像头数据到来时 xff0c 内核会查看队列中是否有缓冲区 v4l2 b
  • PVE7.3 更新源

    xff08 PVE7 1 7 3均可用 xff09 PVE官方源 apt update xff0c apt upgrade都非常的慢 因此要更换国内源 xff0c 注释掉默认企业源 路径 etc apt sources list deb h
  • Ubuntu22.04/Ubuntu20.04安装最新版tensorflow

    废话不多说 xff0c 我们进行安装 tensorflow 的步骤讲解 xff0c 觉得这篇文章对你有帮助的 xff0c 请给本苟蒻一个赞或收藏 Step1 xff1a 首先用命令python3 version看下自己的ubuntu系统有无
  • Windows 上好用的7款下载工具

    Internet Download Manager Internet Download Manager xff08 以下简称 IDM xff09 是 Windows 平台上老牌知名的下载工具 它支持自动捕获剪贴板及浏览器及流媒体网站的音视频
  • mybatis全局 select 语句添加 limit 限制(自定义拦截器实现)

    要实现全局 select 语句的 limit 限制 xff0c 可以通过配置 SQL 拦截器来拦截所有的 SELECT 语句 xff0c 然后在拦截器中添加 LIMIT 条件 具体实现步骤如下 xff1a 创建一个实现了 org apach
  • java 日期校验yyyymmdd

    package com wl cigrec util public class DateUtil 判断参数的格式是否为 yyyyMMdd 格式的合法日期字符串 64 author Liang Wang 64 since 02 24 15 6
  • Ubuntu 回收站目录

    Ubuntu 回收站目录 local share Trash files 对于一些无法在桌面清空的文件 xff0c 可以进入该目录采用 sudo rm 命令删除
  • 音视频采集封装到直播推流原理

    上次好早之前也写过一篇 xff0c 随着工作的深入对这块知识又巩固了一遍 xff0c 算是一个重写和扩展版 旧的总结跳转 xff0c 那么有啥不同呢 xff1f 1 介绍协议的优缺点以及怎么选择 2 会介绍压缩编码的原理 3 测试关注的质量
  • linux操作系统启动及排错详解

    linux操作系统的启动详解过程 xff1a 第一步 xff1a 首先BIOS初始化硬件设备和基本的硬件驱动 检测核心硬件设备的状况 xff0c 设备良好则探测引导程序 从usb cdrom 硬盘 并将引导程序载入内存 xff0c 将控制权
  • Rust 语言新人入门指南

    首先 xff0c 学习 Rust 不能急躁 如果你抱着之前 1 天上手 Python 2 天入门 Go 的经验和优越感来学习 Rust 的话 xff0c 你可能会遭遇严重的失败感 如果你来自 Haskell Ocaml 等函数式语言社区 x
  • 你!们!居!然!用!rust!

    今年 xff0c Rust 无疑是开发者圈子里最火的词之一了 6 月 18 日 xff0c Facebook xff08 脸书 xff09 发布加密数字货币项目白皮书 该数字货币被命名为 Libra 使用 rust 开发 xff1b 7月
  • 【Rust每周一库】Tokei - 统计代码行数等信息的实用工具

    Tokei是一个按语言统计代码行数等统计信息的工具 其实这些信息还是非常有用的 xff0c 首先程序猿可以用它来估计别人的实力或者观察自己实力成长的速度 xff08 神马 xff0c 行数论英雄么 xff1f xff09 其次 xff0c
  • 入门 Rust 开发 WebAssembly

    本文来自 AirCloud 的知乎投稿 xff1a https zhuanlan zhihu com p 104299612 写在前面 可以用于开发 WebAssembly 的语言比较多 xff0c 笔者之前也尝试过 AssemblyScr
  • 【Rust每周一知】Rust 异步入门

    这是一篇博文翻译 xff0c 略有删减 xff0c 整理代码方便统一阅读 xff0c Github链接 xff1a https github com lesterli rust practice tree master head first
  • 【Rust日报】2020-03-05 在 Flutter 插件上运行原生 Rust!

    在 Flutter 插件上运行原生 Rust xff01 该项目是一个 flutter 的插件模板 xff0c 它对所有可用的 iOS 和 Android 架构提供了交叉编译原生 Rust 代码的开箱即用支持 xff0c Dart 语言可以
  • 【Rust日报】2020-04-13 Ruma,Flutter RS,Valora,Rust SSH,mathbench

    1 Ruma死掉了 Ruma万岁 于2020年4月10日 Ruma is dead long live Ruma April 10 2020作者 xff1a Jonas Platte Ruma是一组由Matrix homeserver服务器
  • 【重磅】用Rust重写Linux内核模块体验

    本文来自知乎 https zhuanlan zhihu com p 137077998 作者 Kevin Wang 最近 xff0c 我用Rust重写了一个2W 43 行C代码的linux内核模块 在此记录一点经验 我此前没写过内核模块 x
  • 硬核教程 - 使用Rust编写网游FPS外挂辅助

    优势 xff1a Rust没有GC 效率和C 43 43 一样快 本贴子主要用于观摩和学习调用windows api xff0c 禁止用于某些用途 目标 扫描屏幕敌人出现红色的名字 xff0c 达到自动开枪的目的 效果 爆破模式和狙击枪使用
  • SRFBN的PyTorch实现

    SRFBN的PyTorch实现 源码 xff1a https github com Paper99 SRFBN CVPR19 依赖项 xff1a Python 3 Anaconda is recommended skimageimageio
  • 【crossbeam系列】4 crossbeam-channel:加强版channel

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