|
|
@ -102,7 +102,7 @@ fn main() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
以上代码中,`String`底层的字符串是存储在堆上,被没有实现`Copy`特征,当它被发送后,会将所有权从发送端的`s`转移给接收端的`received`,之后`s`将无法被使用:
|
|
|
|
以上代码中,`String`底层的字符串是存储在堆上,并没有实现`Copy`特征,当它被发送后,会将所有权从发送端的`s`转移给接收端的`received`,之后`s`将无法被使用:
|
|
|
|
```console
|
|
|
|
```console
|
|
|
|
error[E0382]: borrow of moved value: `s`
|
|
|
|
error[E0382]: borrow of moved value: `s`
|
|
|
|
--> src/main.rs:10:31
|
|
|
|
--> src/main.rs:10:31
|
|
|
@ -178,10 +178,10 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
|
|
- 需要所有的发送者都被`drop`掉后,接收者`rx`才会收到错误,进而跳出`for`循环,最终结束主线程
|
|
|
|
- 需要所有的发送者都被`drop`掉后,接收者`rx`才会收到错误,进而跳出`for`循环,最终结束主线程
|
|
|
|
- 这里虽然用了`clone`但是并不会影响性能,因为它并不在热点代码路径中,仅仅会被执行一次
|
|
|
|
- 这里虽然用了`clone`但是并不会影响性能,因为它并不在热点代码路径中,仅仅会被执行一次
|
|
|
|
- 由于两个子线程谁创建完成是未知的,因此哪条消息先发送也是未知的,最终主线程的输出顺序也不确定
|
|
|
|
- 由于两个子线程谁先创建完成是未知的,因此哪条消息先发送也是未知的,最终主线程的输出顺序也不确定
|
|
|
|
|
|
|
|
|
|
|
|
## 消息顺序
|
|
|
|
## 消息顺序
|
|
|
|
上述第三点的消息顺序仅仅是因为线程创建引起的,并不代表通道中的线程是无序的,对于通道而言,消息的发送顺序和接收顺序是一直的,满足`FIFO`原则(先进先出)。
|
|
|
|
上述第三点的消息顺序仅仅是因为线程创建引起的,并不代表通道中的消息是无序的,对于通道而言,消息的发送顺序和接收顺序是一致的,满足`FIFO`原则(先进先出)。
|
|
|
|
|
|
|
|
|
|
|
|
由于篇幅有限,具体的代码这里就不再给出,感兴趣的读者可以自己验证下。
|
|
|
|
由于篇幅有限,具体的代码这里就不再给出,感兴趣的读者可以自己验证下。
|
|
|
|
|
|
|
|
|
|
|
@ -228,7 +228,7 @@ fn main() {
|
|
|
|
从输出还可以看出,`发送之前`和`发送之后`是连续输出的,没有受到接收端主线程的任何影响,因此通过`mpsc::channel`创建的通道是异步通道。
|
|
|
|
从输出还可以看出,`发送之前`和`发送之后`是连续输出的,没有受到接收端主线程的任何影响,因此通过`mpsc::channel`创建的通道是异步通道。
|
|
|
|
|
|
|
|
|
|
|
|
#### 同步通道
|
|
|
|
#### 同步通道
|
|
|
|
与异步通道相反,同步通道**发送消息是阻塞的,只有在消息被接收后才解除阻塞**例如:
|
|
|
|
与异步通道相反,同步通道**发送消息是阻塞的,只有在消息被接收后才解除阻塞**,例如:
|
|
|
|
```rust
|
|
|
|
```rust
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::thread;
|
|
|
|
use std::thread;
|
|
|
@ -370,8 +370,8 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
|
|
解决办法很简单,`drop`掉`send`即可:在代码中的注释下面添加一行`drop(send);`。
|
|
|
|
解决办法很简单,`drop`掉`send`即可:在代码中的注释下面添加一行`drop(send);`。
|
|
|
|
|
|
|
|
|
|
|
|
## mpmc、更好的性能
|
|
|
|
## mpmc 更好的性能
|
|
|
|
如果你需要mpmc(多发送者,多接收者)或者需要更高的性能,可以考虑第三方库:
|
|
|
|
如果你需要mpmc(多发送者,多接收者)或者需要更高的性能,可以考虑第三方库:
|
|
|
|
|
|
|
|
|
|
|
|
- [**crossbeam-channel**](https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel), 老牌强库,功能较全,性能较强,之前是独立的库,但是后面合并到了`crossbeam`主仓库中
|
|
|
|
- [**crossbeam-channel**](https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel), 老牌强库,功能较全,性能较强,之前是独立的库,但是后面合并到了`crossbeam`主仓库中
|
|
|
|
- [**flume**](https://github.com/zesterer/flume), 官方给出的性能数据要比crossbeam更好些,但是貌似最近没怎么更新
|
|
|
|
- [**flume**](https://github.com/zesterer/flume), 官方给出的性能数据某些场景要比crossbeam更好些
|
|
|
|