Rust 如何同时运行包含借用TcpStream的期货?
我试图使这个代码段并发运行,而不是按顺序运行,因为对等点的数量可能是一个很大的值。我使用的是Rust 如何同时运行包含借用TcpStream的期货?,rust,async-await,future,asyncsocket,Rust,Async Await,Future,Asyncsocket,我试图使这个代码段并发运行,而不是按顺序运行,因为对等点的数量可能是一个很大的值。我使用的是async_std 1.4和rust1.41 pub结构对等{ pub peer_id:String, 发布tcp_流:Arc, 发布公钥:[u8;32], } 异步fn将\u发送到\u所有\u对等方(消息:协议,对等方:&HashMap)->结果{ 对于对等中的对等。值(){ 让mut stream=&*peer.tcp_stream; stream.write_all(&bincode::序列化(&m
async_std 1.4
和rust1.41
pub结构对等{
pub peer_id:String,
发布tcp_流:Arc,
发布公钥:[u8;32],
}
异步fn将\u发送到\u所有\u对等方(消息:协议,对等方:&HashMap)->结果{
对于对等中的对等。值(){
让mut stream=&*peer.tcp_stream;
stream.write_all(&bincode::序列化(&message)?)。wait?;
}
好(())
}
由于在async\u std::task::spawn
中包装我创建并使用的未来需要一个静态生存期,因此我尝试使用futures::future::future::join\u all
方法时没有任何运气。以下是我尝试过的:
async fn向所有对等方发送(消息:协议、对等方:&HashMap){
让handles=peers.values().进入|iter().map(| peer |{
任务::繁殖(
异步的{
让mut stream=&*peer.tcp_stream;
如果let Err(Err)=流
.write_all(&bincode::序列化(&message).unwrap())
.等待
{
错误!(“写入tcp_流时出错:{}”,错误);
}
}
)
});
期货::期货::加入所有(句柄)。等待;
}
我确信我缺少了一些方法,谢谢你的帮助 你试过类似的东西吗
let handles = peers.values().into_iter().map(|peer| {
let mut stream = &*peer.tcp_stream;
stream.write_all(&bincode::serialize(&message).unwrap())
}
let results = futures::future::join_all(handles).await
?
请注意.map闭包是如何不等待的,而是直接返回一个未来,然后传递给join_all,然后等待 由于您试图同时发送消息,因此每个任务都必须有自己的消息副本:
use async_std::{task, net::TcpStream};
use futures::{future, io::AsyncWriteExt};
use serde::Serialize;
use std::{
collections::HashMap,
error::Error,
sync::Arc,
};
pub struct Peer {
pub peer_id: String,
pub tcp_stream: Arc<TcpStream>,
pub public_key: [u8; 32],
}
#[derive(Serialize)]
struct Protocol;
async fn send_to_all_peers(
message: Protocol,
peers: &HashMap<String, Peer>)
-> Result<(), Box<dyn Error>>
{
let msg = bincode::serialize(&message)?;
let handles = peers.values()
.map(|peer| {
let msg = msg.clone();
let socket = peer.tcp_stream.clone();
task::spawn(async move {
let mut socket = &*socket;
socket.write_all(&msg).await
})
});
future::try_join_all(handles).await?;
Ok(())
}
使用async_std:{task,net::TcpStream};
使用未来:{future,io::asyncWriteText};
使用serde::序列化;
使用std::{
集合::HashMap,
错误::错误,
sync::Arc,
};
发布结构对等{
pub peer_id:String,
发布tcp_流:Arc,
发布公钥:[u8;32],
}
#[导出(序列化)]
结构协议;
异步fn向所有\u对等方发送\u(
信息:协议,
对等点:&哈希映射)
->结果
{
让msg=bincode::序列化(&message)?;
让handles=peers.values()
.map(| peer |{
让msg=msg.clone();
让socket=peer.tcp_stream.clone();
任务::生成(异步移动){
让mut socket=&*socket;
socket.write_all(&msg)。等待
})
});
未来::尝试加入所有(句柄)。等待?;
好(())
}
我在另一个生命周期问题上尝试了这一点,这是错误的基本jist:rust stream.write\u all(message)返回一个引用当前函数拥有的数据的值
谢谢!这就解决了问题。我希望我能绕过克隆Arc
,但我想这是不可能安全完成的。