Ch 27: std::process - 子进程管理
std::process模块提供了进程管理的完整功能,包括子进程的创建、等待、管道通信和终止。
2. Child - 子进程句柄
Section titled “2. Child - 子进程句柄”从Command::spawn返回的Child结构体:
use std::process::{Command, Stdio};use std::io::{Read, Write};
fn main() { let mut child = Command::new("cat") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("启动进程失败");
// 获取子进程的stdin if let Some(ref mut stdin) = child.stdin { stdin.write_all(b"Hello from parent!").unwrap(); }
// 获取子进程的stdout if let Some(ref mut stdout) = child.stdout { let mut buffer = String::new(); stdout.read_to_string(&mut buffer).unwrap(); println!("子进程输出: {}", buffer); }}3. Stdio - 标准流配置
Section titled “3. Stdio - 标准流配置”pub enum Stdio { Inherited, // 继承父进程的标准流 Piped, // 创建管道 Null, // 重定向到/dev/null FromRaw(FileDesc), // 从原始文件描述符创建}创建带管道的子进程:
use std::process::{Command, Stdio};
fn main() { // 创建双向管道 let mut child = Command::new("python3") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .expect("启动失败");}4. wait - 等待子进程结束
Section titled “4. wait - 等待子进程结束”use std::process::Command;
fn main() { let mut child = Command::new("sleep") .arg("2") .spawn() .expect("启动失败");
println!("等待子进程结束...");
// 阻塞等待 let status = child.wait().expect("等待失败");
println!("进程退出状态: {}", status); println!("是否成功: {}", status.success()); println!("退出码: {:?}", status.code());}方法签名:
impl Child { pub fn wait(&mut self) -> Result<ExitStatus> pub fn try_wait(&mut self) -> Result<Option<ExitStatus>>}5. try_wait - 非阻塞检查
Section titled “5. try_wait - 非阻塞检查”try_wait()非阻塞地检查进程状态:
use std::process::Command;use std::time::Duration;
fn main() { let mut child = Command::new("sleep") .arg("10") .spawn() .expect("启动失败");
// 非阻塞检查 loop { match child.try_wait().expect("检查失败") { Some(status) => { println!("进程已结束: {}", status); break; } None => { println!("进程仍在运行..."); std::thread::sleep(Duration::from_secs(1)); } } }}6. kill - 终止子进程
Section titled “6. kill - 终止子进程”use std::process::{Command, Stdio};use std::time::Duration;
fn main() { let mut child = Command::new("sleep") .arg("100") .stdout(Stdio::null()) .spawn() .expect("启动失败");
println!("子进程PID: {}", child.id());
// 等待一小段时间 std::thread::sleep(Duration::from_secs(1));
// 终止进程 child.kill().expect("终止失败");
// 获取退出状态 let status = child.wait().expect("等待失败"); println!("进程被终止,状态: {}", status);}方法签名:
impl Child { pub fn kill(&mut self) -> Result<()>}7. 管道与进程通信
Section titled “7. 管道与进程通信”父子进程通过管道通信:
use std::process::{Command, Stdio};use std::io::Read;
fn main() { // 创建管道 let mut child = Command::new("wc") .arg("-w") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .spawn() .expect("启动失败");
// 写入数据 let text = "hello world from rust process"; if let Some(ref mut stdin) = child.stdin { use std::io::Write; stdin.write_all(text.as_bytes()).unwrap(); }
// 读取结果 let mut output = String::new(); if let Some(ref mut stdout) = child.stdout { stdout.read_to_string(&mut output).unwrap(); }
println!("字数统计: {}", output.trim());}8. wait_with_output - 等待并获取所有输出
Section titled “8. wait_with_output - 等待并获取所有输出”便捷方法,一步完成等待和输出获取:
use std::process::Command;
fn main() { let output = Command::new("ls") .arg("-la") .output() .expect("执行失败");
// output包含stdout、stderr和status println!("退出码: {:?}", output.status.code()); println!("stdout: {}", String::from_utf8_lossy(&output.stdout));}9. ExitStatus - 退出状态
Section titled “9. ExitStatus - 退出状态”use std::process::{Command, ExitStatus};
fn main() { let output = Command::new("ls") .arg("/tmp") .output() .expect("执行失败");
let status = output.status;
// 检查退出状态 if status.success() { println!("命令执行成功"); }
// 获取退出码 if let Some(code) = status.code() { println!("退出码: {}", code); }}Unix特定方法:
impl ExitStatus { pub fn signal(&self) -> Option<i32> pub fn core_dumped(&self) -> bool pub fn stopped(&self) -> Option<i32>}10. 注意事项
Section titled “10. 注意事项”- 僵尸进程:必须调用
wait()回收子进程资源 - 管道缓冲:管道有缓冲区限制,避免写入过多数据
- 死锁风险:同时读写父子进程时注意避免循环依赖
- 信号处理:子进程可能因信号被终止
- 资源清理:
Child被drop时会自动wait(如果还没wait)
11. 总结
Section titled “11. 总结”std::process提供了完整的进程管理能力:
Child- 子进程句柄,管理stdin/stdout/stderrStdio- 标准流配置(继承/管道/null)wait()/try_wait()- 等待进程结束kill()- 终止进程ExitStatus- 退出状态检查
这些API是Rust实现进程间通信(IPC)的基础。