Rust系统进程信息库darwin-libproc-sys的使用:macOS平台下高效获取进程状态与系统调用信息
Rust系统进程信息库darwin-libproc-sys的使用:macOS平台下高效获取进程状态与系统调用信息
darwin-libproc-sys是一个为macOS平台提供的低级Rust绑定库,用于访问libproc
系统库的功能。
特性
该库提供对macOS XNU内核4903.221.2版本中libproc
功能的非安全低级绑定。
安装
在项目目录中运行以下Cargo命令:
cargo add darwin-libproc-sys
或直接在Cargo.toml中添加:
darwin-libproc-sys = "0.2.0"
示例代码
以下是一个使用darwin-libproc-sys获取进程信息的完整示例:
// 导入必要的库
use darwin_libproc_sys::proc::*;
use std::mem;
use std::ptr;
fn main() {
// 获取当前进程ID
let pid = unsafe { proc_pidinfo(proc_selfpid(), PROC_PIDLISTTHREADS, 0, ptr::null_mut(), 0) };
if pid <= 0 {
eprintln!("Failed to get process info");
return;
}
// 获取进程名称
let mut name_buffer: [u8; 256] = [0; 256];
let result = unsafe {
proc_name(proc_selfpid(), name_buffer.as_mut_ptr() as *mut libc::c_void, name_buffer.len() as u32)
};
if result > 0 {
let process_name = String::from_utf8_lossy(&name_buffer[..result as usize]);
println!("Process name: {}", process_name);
} else {
eprintln!("Failed to get process name");
}
// 获取线程信息
let thread_count = unsafe { proc_pidinfo(proc_selfpid(), PROC_PIDLISTTHREADS, 0, ptr::null_mut(), 0) };
println!("Thread count: {}", thread_count);
}
完整示例代码
以下是一个更完整的示例,展示如何获取多个进程信息:
use darwin_libproc_sys::proc::*;
use std::{ptr, mem};
fn main() {
// 获取所有进程ID
let mut pids = vec![0; 2048];
let pid_count = unsafe {
proc_listpids(PROC_ALL_PIDS, 0, pids.as_mut_ptr() as *mut libc::c_void,
(pids.len() * mem::size_of::<u32>()) as i32)
} / mem::size_of::<u32>() as i32;
if pid_count <= 0 {
eprintln!("Failed to get process list");
return;
}
println!("Found {} processes", pid_count);
// 遍历前10个进程获取信息
for &pid in pids.iter().take(10) {
if pid == 0 {
continue;
}
// 获取进程名称
let mut name_buffer = [0u8; 256];
let name_len = unsafe {
proc_name(pid, name_buffer.as_mut_ptr() as *mut libc::c_void, name_buffer.len() as u32)
};
if name_len > 0 {
let name = String::from_utf8_lossy(&name_buffer[..name_len as usize]);
println!("PID: {}, Name: {}", pid, name);
} else {
println!("PID: {} (name unavailable)", pid);
}
// 获取进程路径
let mut path_buffer = [0u8; libc::PATH_MAX as usize];
if unsafe { proc_pidpath(pid, path_buffer.as_mut_ptr() as *mut libc::c_void, path_buffer.len() as u32) } > 0 {
let path = String::from_utf8_lossy(&path_buffer);
println!(" Path: {}", path.trim_end_matches('\0'));
}
// 获取线程数
let thread_count = unsafe { proc_pidinfo(pid, PROC_PIDLISTTHREADS, 0, ptr::null_mut(), 0) };
println!(" Threads: {}", thread_count);
}
}
文档
完整API文档可在文档网站查看。
许可证
该项目采用双许可证:
- Apache License 2.0
- MIT license
注意事项
- 该库提供的是非安全(unsafe)FFI绑定
- 仅适用于macOS平台
- 如需更安全的包装,可参考darwin-libproc crate
所有权
主要维护者:svartalf
1 回复
Rust系统进程信息库darwin-libproc-sys使用指南
简介
darwin-libproc-sys
是一个Rust库,提供了对macOS系统libproc
库的绑定,允许开发者在macOS平台下高效获取进程状态和系统调用信息。这个库特别适合需要监控或管理系统进程的应用程序开发。
主要功能
- 获取进程列表
- 查询进程信息(名称、PID、状态等)
- 获取进程路径
- 查询线程信息
- 获取系统调用信息
安装
在Cargo.toml中添加依赖:
[dependencies]
darwin-libproc-sys = "0.1"
基本使用方法
1. 获取所有进程ID
use darwin_libproc_sys::proc;
fn main() {
let pids = proc::listpids(proc::ProcType::ProcAllPIDS, 0).unwrap();
println!("Running processes: {:?}", pids);
}
2. 获取进程信息
use darwin_libproc_sys::proc;
fn main() {
let pid = 1234; // 替换为你想查询的PID
let info = proc::pidinfo::<proc::ProcTaskAllInfo>(pid, 0).unwrap();
println!("Process {} info: {:?}", pid, info);
}
3. 获取进程路径
use darwin_libproc_sys::proc;
fn main() {
let pid = 1234; // 替换为你想查询的PID
let path = proc::pidpath(pid).unwrap();
println!("Process {} path: {}", pid, path);
}
4. 获取进程名称
use darwin_libproc_sys::proc;
fn main() {
let pid = 1234; // 替换为你想查询的PID
let name = proc::name(pid).unwrap();
println!("Process {} name: {}", pid, name);
}
高级用法
获取线程信息
use darwin_libproc_sys::proc;
fn main() {
let pid = 1234; // 替换为你想查询的PID
let threads = proc::listpidthreads(pid).unwrap();
println!("Threads for process {}: {:?}", pid, threads);
for tid in threads {
let thread_info = proc::threadinfo(pid, tid).unwrap();
println!("Thread {} info: {:?}", tid, thread_info);
}
}
监控进程状态变化
use darwin_libproc_sys::proc;
use std::thread;
use std::time::Duration;
fn monitor_process(pid: i32) {
loop {
match proc::pidinfo::<proc::ProcTaskAllInfo>(pid, 0) {
Ok(info) => {
println!("Process {} status: {:?}", pid, info.pbsd.pbi_status);
},
Err(e) => {
println!("Error or process ended: {}", e);
break;
}
}
thread::sleep(Duration::from_secs(1));
}
}
完整示例Demo
以下是一个结合多个功能的完整示例,演示如何监控特定进程的状态变化:
use darwin_libproc_sys::proc;
use std::thread;
use std::time::Duration;
fn main() {
// 获取当前所有进程列表
let all_pids = proc::listpids(proc::ProcType::ProcAllPIDS, 0).unwrap();
println!("当前系统进程数: {}", all_pids.len());
// 获取第一个进程的详细信息作为示例
if let Some(&pid) = all_pids.first() {
println!("\n监控进程 {} 的详细信息:", pid);
// 获取并显示进程名称
if let Ok(name) = proc::name(pid) {
println!("进程名称: {}", name);
}
// 获取并显示进程路径
if let Ok(path) = proc::pidpath(pid) {
println!("进程路径: {}", path);
}
// 获取并显示进程完整信息
if let Ok(info) = proc::pidinfo::<proc::ProcTaskAllInfo>(pid, 0) {
println!("进程状态: {:?}", info.pbsd.pbi_status);
println!("进程优先级: {}", info.ptinfo.pti_priority);
}
// 监控进程状态变化
println!("\n开始监控进程状态变化...");
monitor_process(pid);
}
}
fn monitor_process(pid: i32) {
let mut prev_status = None;
loop {
match proc::pidinfo::<proc::ProcTaskAllInfo>(pid, 0) {
Ok(info) => {
// 只在状态变化时打印
if prev_status != Some(info.pbsd.pbi_status) {
println!("[PID {}] 状态变化: {:?}", pid, info.pbsd.pbi_status);
prev_status = Some(info.pbsd.pbi_status);
}
},
Err(e) => {
println!("错误或进程已结束: {}", e);
break;
}
}
thread::sleep(Duration::from_secs(1));
}
}
注意事项
- 需要macOS系统支持
- 某些操作可能需要root权限
- 错误处理很重要,因为进程可能在任何时候终止
- 频繁查询可能会影响系统性能
性能建议
- 批量获取信息而不是单个查询
- 缓存不常变化的信息
- 合理设置轮询间隔
这个库为macOS系统进程监控和管理提供了强大的底层支持,可以用于开发系统监控工具、调试工具或任务管理器等应用。