1. std::sync::mpsc::channel

支持多Sender,仅支持1个Receiver,可保证接收消息的顺序与发送的顺序一致。

pub fn channel<T>() -> (Sender<T>, Receiver<T>)

会创建新的async channel,返回的是sender/receiver对。
所有经由Sender发送的数据顺序,与 在Receiver端收到的数据顺序是一致的。
没有任何send操作可阻塞线程,该channel可认为是具有“无限buffer”的,而recv操作将阻塞直到有消息过来。(而对于sync_channel,当其达到buffer limit时会阻塞)。

Sender可复制多次send到同一channel,但仅支持一个`Receiver``。

Receiver断开时,Sender的send操作会受到SendError。同理,当Sender断开时,Receiver的recv操作将受到RecvError。

示例:

use std::sync::mpsc::channel;
use std::thread;let (sender, receiver) = channel();// Spawn off an expensive computation
thread::spawn(move|| {sender.send(expensive_computation()).unwrap();
});// Do some useful work for awhile// Let's see what that answer was
println!("{:?}", receiver.recv().unwrap());

2. crossbeam_channel

为多生产者,多接收者的消息传输通道。
channel通道的创建方式有2种:

  • bounded:通道具有容量上限,即通道内同时容纳的消息数有限制。
use crossbeam_channel::bounded;// Create a channel that can hold at most 5 messages at a time.
let (s, r) = bounded(5);// Can send only 5 messages without blocking.
for i in 0..5 {s.send(i).unwrap();
}// Another call to `send` would block because the channel is full.
// s.send(5).unwrap();
  • unbounded:通道的容量无上限,即通道内可同时容纳任意多的消息。
use crossbeam_channel::unbounded;// Create an unbounded channel.
let (s, r) = unbounded();// Can send any number of messages into the channel without blocking.
for i in 0..1000 {s.send(i).unwrap();
}

特例情况为0容量通道,即通道内无法容纳消息。对应的,发送和接收操作必须成对出现:

use std::thread;
use crossbeam_channel::bounded;// Create a zero-capacity channel.
let (s, r) = bounded(0);// Sending blocks until a receive operation appears on the other side.
thread::spawn(move || s.send("Hi!").unwrap());// Receiving blocks until a send operation appears on the other side.
assert_eq!(r.recv(), Ok("Hi!"));

支持复制Sender和Receiver:

use crossbeam_channel::unbounded;let (s1, r1) = unbounded();
let (s2, r2) = (s1.clone(), r1.clone());
let (s3, r3) = (s2.clone(), r2.clone());s1.send(10).unwrap();
s2.send(20).unwrap();
s3.send(30).unwrap();assert_eq!(r3.recv(), Ok(10));
assert_eq!(r1.recv(), Ok(20));
assert_eq!(r2.recv(), Ok(30));

当所有的Senders或Receivers 与通道连接断开,则通道处于disconnected状态,消息不再可发送成功,但是通道内剩余的消息仍然可被接收。对处于disconnected状态的通道进行发送或接收操作都不会阻塞:

use crossbeam_channel::{unbounded, RecvError};let (s, r) = unbounded();
s.send(1).unwrap();
s.send(2).unwrap();
s.send(3).unwrap();// The only sender is dropped, disconnecting the channel.
drop(s);// The remaining messages can be received.
assert_eq!(r.recv(), Ok(1));
assert_eq!(r.recv(), Ok(2));
assert_eq!(r.recv(), Ok(3));// There are no more messages in the channel.
assert!(r.is_empty());// Note that calling `r.recv()` does not block.
// Instead, `Err(RecvError)` is returned immediately.
assert_eq!(r.recv(), Err(RecvError));

发送和接收操作支持3种模式:

  • 非阻塞(立即返回成功或失败)
  • 阻塞(等待操作成功或通道disconnected)
  • 超时阻塞(仅阻塞一段时间)
use crossbeam_channel::{bounded, RecvError, TryRecvError};let (s, r) = bounded(1);// Send a message into the channel.
s.send("foo").unwrap();// This call would block because the channel is full.
// s.send("bar").unwrap();// Receive the message.
assert_eq!(r.recv(), Ok("foo"));// This call would block because the channel is empty.
// r.recv();// Try receiving a message without blocking.
assert_eq!(r.try_recv(), Err(TryRecvError::Empty));// Disconnect the channel.
drop(s);// This call doesn't block because the channel is now disconnected.
assert_eq!(r.recv(), Err(RecvError));

借助try_iter可非阻塞的获取通道内的所有消息:

use crossbeam_channel::unbounded;let (s, r) = unbounded();
s.send(1).unwrap();
s.send(2).unwrap();
s.send(3).unwrap();
// No need to drop the sender.// Receive all messages currently in the channel.
let v: Vec<_> = r.try_iter().collect();assert_eq!(v, [1, 2, 3]);

参考资料

[1] https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html
[2] https://docs.rs/crossbeam-channel/0.5.1/crossbeam_channel/

Rust中的channel相关推荐

  1. Draconian,自由或保姆状态:Java,C#,C,C ++,Go和Rust中的并发意识形态

    为什么我们需要并发 (Why we need Concurrency) Once, there was a good old time when clock speed doubled every 1 ...

  2. netty获取玩家chanel_Netty中的Channel

    在JDK中就有Channel的概念了. 数据的读写都要通过Channel进行. 既然Netty是封装了JDK, 同样它也有自己的Channel. 一个是服务端Chanel(NioServerSocke ...

  3. netty系列之:netty中的Channel详解

    文章目录 简介 Channel详解 异步IO和ChannelFuture Channel的层级结构 释放资源 事件处理 总结 简介 Channel是连接ByteBuf和Event的桥梁,netty中的 ...

  4. 在.NET Core中使用Channel(一)

    我最近一直在熟悉.net Core中引入的新Channel<T>类型.我想在它第一次发布的时候我了解过它,但是有关文章非常非常少,我不能理解它们与其他队列有什么不同. 在使用了一段时间后, ...

  5. Rust 中的继承与代码复用

    Rust 中的继承与代码复用 在学习Rust过程中突然想到怎么实现继承,特别是用于代码复用的继承,于是在网上查了查,发现不是那么简单的. C++的继承 首先看看c++中是如何做的. 例如要做一个场景结 ...

  6. Rust中Turbofish之函数后面双冒号(::)用法

    RUST中的语法,Turbofish通常用于在表达式中为泛型类型.函数或方法指定参数. 1. Turbofish语法 大部分时候当涉及到泛型时,编译器可以自动推断出泛型参数: // v must be ...

  7. rust全息要啥才能做_在 Rust 中不能做什么

    编者注:上周 Armin 在自己的博客上首次发布了这个版本.如果你想再次阅读这篇文章,或者想看看 Armin 还在做什么,一定要去看看. 去年一直很有趣,因为我们用 Rust 建造了很多好东西,并且这 ...

  8. c++ enum 给定类型_在 Rust 中创建 C/C++ API

    Rust 是一种神奇的语言,有着更好的生态系统.许多 Rust 的设计决策都非常适合向现有的C/C++系统添加新功能,或者逐步替换这些系统的部分! 当我尝试为 Rust 创建 C++ API 时,我发 ...

  9. rust笔记7 rust中的包管理

    rust相比于C++,一个优势在于有一个现代化的包管理系统,我们不用搞各种命令空间和依赖的问题.这里主要记录了一般文件打包的方式. rust中声明包的关键字是mod,如果是公共的,则需要声明为pub ...

最新文章

  1. H3C LMI协议标准
  2. Mybatis中的resultType与resultMap区别
  3. time zone issue in text processing
  4. UML学习-活动图创建
  5. jmeter负载测试测试_使用Apache JMeter负载测试Web应用程序
  6. [BZOJ 5074] 小B的数字
  7. Python | Socket02 - 使用with语句建立一个TCP服务器(阻塞+单线程),将TCP客户端发过来的字符串原路返回
  8. bzoj 2527: [Poi2011]Meteors
  9. Unity手游开发与实战
  10. 怎么去掉字符串最后一个逗号
  11. 双非计算机考研复试怎么办,【计算机考研】985、211VS双非,复试时导师会有歧视吗?...
  12. 全国乡镇边界及名称的下载与格式转换方法(水经注万能地图X3.1+CASS10.1.5组合拳)
  13. 【读书笔记】浪潮之巅——方法论篇
  14. 日系P2P原理探究(一) — Winny元祖: Freenet
  15. 将HDC保存为BMP文件
  16. 2023年美赛C题Wordle预测问题三、四建模及Python代码详细讲解
  17. 5h是什么意思_鱼杆5H什么意思?
  18. android 虚拟键盘的显示与隐藏问题
  19. Orphaned pod found - but volume paths are still present on disk的处理
  20. Android app如何加密?

热门文章

  1. 多表联查--01---LEFT JOIN 实现多表联查
  2. ChatGPT,背后的核心是什么?
  3. ZigBee-CC2530单片机 - 实现计算机串口通讯控制LED发光二极管
  4. DOS命令不需格式化U盘-FAT32轻松转换成NTFS
  5. 字符串解压缩类库(zip、GZIP、QuickLz、snappy、lzf、jzlib)介绍
  6. 分辨率,像素,dp之间的联系
  7. 欺骗的艺术——第二部分(2)
  8. html和css实现导航栏样式
  9. Xshell下载安装教程和使用教程(超详细)
  10. linux- 日志管理