I know this question has been asked by many people, and in the past, either tokio::sync::Mutex was recommended to replace std::sync::Mutex, or it was made to be called in the same task via Channel.
What I want to know is if there is any other way to do this? In the case of my current TcpStream send.
#[tokio::test]
async fn test_send_arc_mutex_tcps() {
async fn one(tcps: Arc<std::sync::Mutex<TcpStream>>, src: String) {
tcps.lock().unwrap().write(src.as_bytes()).await.unwrap();
//-------------------- ^^^^^^ await occurs here, with `tcps.lock().unwrap()` maybe used later
// |
// has type `std::sync::MutexGuard<'_, tokio::net::TcpStream>` which is not `Send`
}
async fn two(tcps: Arc<std::sync::Mutex<TcpStream>>, src: String) {
let w = {
let mut tcps = tcps.lock().unwrap();
tcps.write(src.as_bytes()) // `tcps` does not live long enough
// borrowed value does not live long enough
};
let _ = w.await;
}
let tcps = TcpStream::connect("192.168.1.10:8080").await.unwrap();
let tcps = Arc::new(std::sync::Mutex::new(tcps));
let datum = [
"hello".to_string(),
"rustl".to_string(),
"tokio".to_string(),
];
for data in datum.iter() {
let tcps1 = tcps.clone();
let tcps2 = tcps.clone();
let data1 = data.clone();
let data2 = data.clone();
tokio::spawn(async move {
// error: future cannot be sent between threads safely
one(tcps1, data1).await;
two(tcps2, data2).await;
});
}
}