Ba7*_*chy 6 multithreading rust
这是我的代码:
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()
}
Run Code Online (Sandbox Code Playgroud)
如果连接未在N秒内完成,如何创建线程将被终止或终止的情况?
所有这一切的原因是Rust无法设置套接字连接超时,因此我无法确保程序不会卡住.
oli*_*obk 11
正如@Shepmaster所说:终止线程是个坏主意.
你可以做的是给线程一个Sender
它应该通知你,如果它已成功打开一个连接(甚至可能通过发送你的句柄).然后你可以让你的主线程sleep
等待你想要的时间.当你的线程被唤醒时,它会Receiver
从线程中检查其对应的生命迹象.如果线程没有回答,只是通过降低释放到野外JoinHandle
和Receiver
.它不像消耗cpu时间(它被阻止),而且它不会消耗太多内存.如果它解锁,它将检测到它Sender
没有连接并且可以关闭.
当然你不应该有这些开放线程的bazillions,因为它们仍然使用资源(内存和系统线程句柄),但在正常的系统上,这不是一个问题.
例:
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!(),
}
}
Run Code Online (Sandbox Code Playgroud)
@ker 的回答将始终等待 5 秒,即使连接完成得更快。这是一种类似的方法,超时和网络请求都发生在不同的线程上,第一个完成的获胜:
let (sender, receiver) = mpsc::channel();
let tsender = sender.clone();
let t = thread::spawn(move || {
match sender.send(Ok(net::TcpStream::connect((host.as_str(), port)))) {
Ok(()) => {}, // everything good
Err(_) => {}, // we have been released, don't panic
}
});
let timer = thread::spawn(move || {
thread::sleep(Duration::from_millis(5000));
match tsender.send(Err(MyTimeoutError)) {
Ok(()) => {}, // oops, we timed out
Err(_) => {}, // great, the request finished already
}
});
return receiver.recv().unwrap();
Run Code Online (Sandbox Code Playgroud)
但只要你这样做,你不妨recv_timeout
改为使用:
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
}
});
return receiver.recv_timeout(Duration::from_millis(5000));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3243 次 |
最近记录: |