Multithreading – what is the correct way for rust to create timeouts for threads or functions?
This is my code:
use std::net; use std::thread; extern crate argparse; use argparse::{ArgumentParser,StoreTrue,Store}; fn scan_port(host: &str,port: u16) -> bool { let host = host.to_string(); let port = port; let t = thread::spawn(move || net::TcpStream::connect((host.as_str(),port)).is_ok()); t.join().unwrap() }
If the connection is not completed within N seconds, how to create a situation where the thread will be terminated or terminated?
The reason for all this is that rust can't set the socket connection timeout, so I can't make sure the program won't get stuck
Solution
As @ shepmaster said: terminating threads is a bad idea
What you can do is give the thread a sender. If it has successfully opened a connection (perhaps even by sending your handle), it should notify you Then you can make your main thread sleep wait for the time you want When your thread wakes up, it checks its corresponding receiver from the thread for signs of life If the thread does not answer, just release it into the wild by dropping the joinhandle and the receiver It does not consume CPU time (it is blocked), and it does not consume much memory If it is unlocked, it will detect that the sender is not connected and can be closed
Of course, you shouldn't have these open thread bazillions because they still use resources (memory and system thread handles), but on a normal system, this is not a problem
Example:
use std::net; use std::thread; use std::sync::mpsc; fn scan_port(host: &str,port: u16) -> bool { let host = host.to_string(); let port = port; let (sender,receiver) = mpsc::channel(); let t = thread::spawn(move || { match sender.send(net::TcpStream::connect((host.as_str(),port))) { Ok(()) => {},// everything good Err(_) => {},// we have been released,don't panic } }); thread::sleep(std::time::Duration::new(5,0)); match receiver.try_recv() { Ok(Ok(handle)) => true,// we have a connection Ok(Err(_)) => false,// connecting Failed Err(mpsc::TryRecvError::Empty) => { drop(receiver); drop(t); // connecting took more than 5 seconds false },Err(mpsc::TryRecvError::Disconnected) => unreachable!(),} }