* @brief 测试等待任意子进程 */
| 105 | * @brief 测试等待任意子进程 |
| 106 | */ |
| 107 | void test_wait_any_child(void* /*arg*/) { |
| 108 | klog::Info("=== Wait Any Child Test ==="); |
| 109 | |
| 110 | auto& task_mgr = TaskManagerSingleton::instance(); |
| 111 | auto* current = task_mgr.GetCurrentTask(); |
| 112 | |
| 113 | if (!current) { |
| 114 | klog::Err("Wait Any Child Test: Cannot get current task"); |
| 115 | sys_exit(1); |
| 116 | } |
| 117 | |
| 118 | // 创建多个子进程 |
| 119 | constexpr int kChildCount = 3; |
| 120 | for (int i = 0; i < kChildCount; ++i) { |
| 121 | auto child = kstd::make_unique<TaskControlBlock>( |
| 122 | "AnyChild", 10, child_work, reinterpret_cast<void*>(10 + i)); |
| 123 | child->aux->parent_pid = current->pid; |
| 124 | child->aux->pgid = current->aux->pgid; |
| 125 | auto* child_raw = child.get(); |
| 126 | task_mgr.AddTask(std::move(child)); |
| 127 | Pid child_pid = child_raw->pid; |
| 128 | klog::Info("Parent: created child {} with PID={}", i, child_pid); |
| 129 | } |
| 130 | |
| 131 | // 等待任意子进程 (pid = -1) |
| 132 | int completed = 0; |
| 133 | for (int i = 0; i < kChildCount; ++i) { |
| 134 | int status = 0; |
| 135 | Pid result = |
| 136 | task_mgr.Wait(static_cast<Pid>(-1), &status, false, false).value_or(0); |
| 137 | |
| 138 | if (result > 0) { |
| 139 | klog::Info("Parent: child PID={} exited with status {}", result, status); |
| 140 | completed++; |
| 141 | } else { |
| 142 | klog::Err("Parent: wait failed with result {}", result); |
| 143 | break; |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | if (completed == kChildCount) { |
| 148 | klog::Info("Wait Any Child Test: PASS"); |
| 149 | } else { |
| 150 | klog::Err("Wait Any Child Test: FAIL - only {}/{} children reaped", |
| 151 | completed, kChildCount); |
| 152 | } |
| 153 | |
| 154 | g_tests_completed++; |
| 155 | sys_exit(0); |
| 156 | } |
| 157 | |
| 158 | /** |
| 159 | * @brief 测试非阻塞 wait (WNOHANG) |