Recently I'm trying to monitor the system metrics via psutil
crate. (I know there is another library heim
with async feature.)
I once used AtomicPtr
to wrap the static Process
struct. And the compiler complained nothing. But soon I got run-time errors, when I called the API on the Process
object.
I finally figured out that the pid
of the AtomicPtr<Process>
changed, which led to the error, since the process with new pid did not exist.
Then I tried another way. I implemented the following ProcessWrapper
, it works. And the pid
did not change.
Edit: The ProcessWrapper
is redundant, Process
itself is with Send/Sync
Then here comes my questions:
Process
is without Send
trait? If so, why compiler just acquiesced it?ProcessWrapper
? If exists, how to eliminate it? use psutil::process::Process;
use lazy_static::lazy_static;
use std::process;
use std::sync::{
atomic::{AtomicPtr, AtomicU64, Ordering}, Mutex, Arc
};
lazy_static!{
static ref PROCESS1 : AtomicPtr<Process> = AtomicPtr::new(&mut Process::new(process::id()).unwrap());
static ref PROCESS2: Arc<Mutex<Process>> = Arc::new(Mutex::new(
Process::new(std::process::id()).unwrap()
));
}
fn main() {
let process1 = unsafe{PROCESS1.load(Ordering::SeqCst).as_ref()}.unwrap();
//let process2 = &PROCESS2.lock().unwrap();
println!("{}", process1.pid()); // Unexpected! It is different from the real `process::id`
//println!("{}", process2.pid()); // It performs well, and it also makes the above one valid
println!("{}", process::id());
}
// redundant, the `Process` is with `Send/Sync` trait
use process_wrapper::*;
mod process_wrapper{
use psutil::process::{Process, ProcessResult,MemoryInfo};
use psutil::Percent;
#[derive(Debug)]
pub struct ProcessWrapper{
pub p: Process
}
unsafe impl Send for ProcessWrapper{}
unsafe impl Sync for ProcessWrapper{}
}
AtomicPtr::new(&mut Process::new(process::id()).unwrap())
You create the Process
object on the stack, and store a mutable pointer to that stack object into the AtomicPtr
. Once PROCESS1
has finished initializing, the Process
object is deallocated, and your AtomicPtr
is pointing to uninitialized memory.
psutil:process::Process
is both Send
and Sync
. Arc<Mutex<Process>>
will work fine, and is safe. Not sure why you need an AtomicPtr
.