"Resource temporarily unavailable"非阻塞 Unix 数据报读取



我正在编写一个在自身实例之间来回移动数据的过程。

我收到错误:

线程"main"在"Err值上调用Result::unwrap()"时惊慌失措:OS {代码:11,种类:WillBlock,消息:"资源暂时不可用"}",服务器/src/main.rs:44:37

我目前的实现:

#![feature(duration_constants)]
use std::os::unix::net::UnixDatagram;
use std::time::Duration;
const OLD_PROCESS: &str = "./old";
const NEW_PROCESS: &str = "./new";
fn startup() {
// We send the shutdown notification (the data here doesnt matter) then receive the data.
let socket = UnixDatagram::bind(NEW_PROCESS).unwrap();
println!("sending shutdown signal");
socket.send_to(&[1], OLD_PROCESS).unwrap();
println!("sent shutdown signal");
println!("reciving data");
let mut data = [Default::default(); 4];
socket.recv(&mut data).unwrap();
println!("data: {:?}", data);
std::fs::remove_file(NEW_PROCESS).unwrap();
}
fn process() {
// Once we receive something (indicating a new process has started) we then transfer data.
let socket = UnixDatagram::bind(OLD_PROCESS).unwrap();
println!("awaiting shutdown signal");
// For reading the shutdown signal, we set the socket to non-blocking (like `Mutex::try_read`).
let mut notif_buf = [0; 1];
// It seems by setting nonblocking and the read timeout causes the error:
// ```
// thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', server/src/main.rs:44:37
// ```
socket.set_nonblocking(true).unwrap();
socket
.set_read_timeout(Some(Duration::MICROSECOND))
.unwrap();
println!("socket.read_timeout(): {:?}", socket.read_timeout());
// Our work loop
while notif_buf[0] == 0 {
// Some other work
{
print!(".");
std::thread::sleep(Duration::MILLISECOND);
}
// Check if recieved shutdown signal
socket.recv(&mut notif_buf).unwrap();
}
println!();
println!("recived shutdown signal");
socket.set_nonblocking(false).unwrap();
println!("sending data");
socket.send_to(&[1, 2, 3, 4], NEW_PROCESS).unwrap();
println!("sent data");
std::fs::remove_file(OLD_PROCESS).unwrap();
}
fn main() {
println!("Hello, world!");
// The following processes use it
if std::path::Path::new(OLD_PROCESS).exists() {
println!("non-first");
startup();
process();
}
// The first process creates the socket
else {
println!("first");
process();
}
}

值得注意的是,您现在需要在每个测试结束时手动删除old文件描述符

在最简单的意义上,我想要一个带有UnixDatagram的循环,例如(使用try_readMutex::try_read):

loop {
// Some work ...
match socket.try_read() {
Some(_) => break,
None => continue
}
}

使用时:

socket.set_nonblocking(true).unwrap();
socket.set_read_timeout(Some(Duration::MICROSECOND)).unwrap();

似乎当超时发生时recv通过更改代码来返回Err

// Check if recieved shutdown signal
socket.recv(&mut notif_buf).unwrap();

match socket.recv(&mut notif_buf) {
Ok(_) => break,
Err(_) if err.kind() == ErrorKind::WouldBlock => continue,
_ => unreachable!()
}

这将修复此问题。

最新更新