我应该如何回复频道消息?
How should I respond to a channel message?
现在我有一个后台线程,我正在使用一个通道与之通信。细节并不重要,但我有一个带有变体 Variant(Data, Sender<Response>)
的 enum Message
,因此在后台线程中我可以执行以下操作:
loop {
match message_rx.recv() {
Ok(Message::Variant(data, sender)) => {
let result = do_something(data);
sender.send(result);
}
}
}
并且在前台线程中,
let (response_rx, response_tx) = flume::bounded(1);
message_tx.send(Message::Variant(data, response_tx));
let response = response_rx.recv();
这个解决方案不是并发的(并发也不是这里的特定目标)但它实际上是一个解决方案吗?我受到 Erlang 模式的启发,在该模式中,进程将其 pid 与消息一起发送,以便它可以接收响应。
这确实是一种模式,如您的示例所示,在消息中嵌入回复通信渠道是一种很好的方式,
您可以为它找到不同的实用程序,例如在使用 tokio 的异步环境中,您可以使用 oneshot
, which is a channel that ensures a single message, from the example:
use tokio::sync::oneshot;
#[tokio::main]
async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}
}
现在我有一个后台线程,我正在使用一个通道与之通信。细节并不重要,但我有一个带有变体 Variant(Data, Sender<Response>)
的 enum Message
,因此在后台线程中我可以执行以下操作:
loop {
match message_rx.recv() {
Ok(Message::Variant(data, sender)) => {
let result = do_something(data);
sender.send(result);
}
}
}
并且在前台线程中,
let (response_rx, response_tx) = flume::bounded(1);
message_tx.send(Message::Variant(data, response_tx));
let response = response_rx.recv();
这个解决方案不是并发的(并发也不是这里的特定目标)但它实际上是一个解决方案吗?我受到 Erlang 模式的启发,在该模式中,进程将其 pid 与消息一起发送,以便它可以接收响应。
这确实是一种模式,如您的示例所示,在消息中嵌入回复通信渠道是一种很好的方式,
您可以为它找到不同的实用程序,例如在使用 tokio 的异步环境中,您可以使用 oneshot
, which is a channel that ensures a single message, from the example:
use tokio::sync::oneshot;
#[tokio::main]
async fn main() {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
if let Err(_) = tx.send(3) {
println!("the receiver dropped");
}
});
match rx.await {
Ok(v) => println!("got = {:?}", v),
Err(_) => println!("the sender dropped"),
}
}