diff --git a/ch5/os/src/syscall/process.rs b/ch5/os/src/syscall/process.rs index f0cc4a0..71d9ac4 100644 --- a/ch5/os/src/syscall/process.rs +++ b/ch5/os/src/syscall/process.rs @@ -75,6 +75,21 @@ pub fn sys_exec(path: *const u8) -> isize { } } +/// pid分为如下几种情况: +/// +/// - -1 表示等待任意进程结束 +/// +/// - 1235 表示只等待pid为1234的进程 +/// +/// 返回值会返回如下: +/// +/// - -1 表示要等待的进程不是-1(任意进程)是指定进程, 但是指定进程并没有在children中 +/// +/// - -2 表示目前还没有僵尸进程 +/// +/// - pid 返回被回收的pid +/// + pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize { // 当前进程 这里是父进程 let task = current_task().unwrap(); diff --git a/ch5/user/src/bin/initproc.rs b/ch5/user/src/bin/initproc.rs index 2293ec1..7b885f5 100644 --- a/ch5/user/src/bin/initproc.rs +++ b/ch5/user/src/bin/initproc.rs @@ -6,14 +6,17 @@ use user_lib::{println, wait}; #[no_mangle] fn main() -> i32 { - println!("1"); if sys_fork() == 0 { // 注意需要手动添加\0 转为 c_str + // 启动我们的shell程序 sys_exec("user_shell\0"); } else { + // 所有的进程 最后父进程都会是 initproc进程, 所以我们这里一直等待 子进程是否结束 + // 持续调用wait 进行等待, loop { let mut exit_code: i32 = 0; let pid = wait(&mut exit_code); + //如果 没有进程被回收 则让出cpu, 开始下一轮循环 if pid == -1 { sys_yield(); continue; diff --git a/ch5/user/src/lib.rs b/ch5/user/src/lib.rs index 694219c..bf4305a 100644 --- a/ch5/user/src/lib.rs +++ b/ch5/user/src/lib.rs @@ -38,18 +38,22 @@ fn main() -> i32 { panic!("Cannot find main!"); } +// sys_waitpid如果传的是-1 则表示任何子进程退出都可以, pub fn wait(exit_code: &mut i32) -> isize { loop { match sys_waitpid(-1, exit_code as *mut _) { + // 如果返回-2, 说明还没有僵尸进程, 那就下一轮loop循环继续等待 -2 => { sys_yield(); } + // 如果返回 -1 说明有任意进程结束 // -1 or a real pid exit_pid => return exit_pid, } } } +// 只检测指定pid的进程是否结束 pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize { loop { match sys_waitpid(pid as isize, exit_code as *mut _) { diff --git a/ch5/user/src/user_lang_items/user_console.rs b/ch5/user/src/user_lang_items/user_console.rs index 8bb791d..42fe692 100644 --- a/ch5/user/src/user_lang_items/user_console.rs +++ b/ch5/user/src/user_lang_items/user_console.rs @@ -13,7 +13,7 @@ impl Write for Stdout { } } -// 每次从标准输入读出一个字符 +// 每次从标准输入读出一个字符, 这个会阻塞当前进程 pub fn getchar() -> u8 { let mut c = [0u8; 1]; sys_read(STDIN, &mut c);