unix 进程中waitpid
时间: 2024-10-25 17:17:24 浏览: 14
`waitpid()`是Unix/Linux系统中的一个标准库函数,它的作用是在父进程中等待一个子进程的结束。函数原型通常是这样的:
```c
pid_t waitpid(pid_t pid, int *status, int options);
```
参数说明:
- `pid`:如果为0,`waitpid`会阻塞并等待任意子进程结束;如果提供一个有效的进程ID,则等待那个特定的进程结束。
- `status`:指向一个整数,如果子进程结束了,它会被设置为子进程退出状态码,可以通过`WIFEXITED(status)`和`WEXITSTATUS(status)`、`WIFSIGNALED(status)`和`WTERMSIG(status)`等宏来解析。
- `options`:可选的标志,用于控制等待的行为,比如是否继续等待其他子进程(`WNOHANG`),是否返回所有子进程的状态(`WUNTRACED`)等。
当调用`waitpid()`后,父进程会暂时挂起,直到指定的子进程终止。然后,它可以获取到子进程的退出信息,并可以选择性的继续等待下一个子进程,或者结束整个父进程的运行。
使用`waitpid()`的一个常见场景是父子进程通信,尤其是那些需要父进程处理子进程退出后的清理工作的程序。
相关问题
用fork()创处一个子进程。 子进程用execl或execve执行1s命令。 父进程调用waitpid的数等待子进程结束后,打印“child ended, father ending
在Unix/Linux系统中,你可以使用`fork()`函数创建一个新的子进程。`fork()`函数会返回两个进程ID(PID),一个是父进程的,另一个是新创建子进程的。如果`fork()`成功,父进程将得到0;而子进程则会得到其自身的PID。
一旦创建了子进程,你可以通过`execl()`或`execve()`这两个系统调用来替换子进程的当前进程映射,让子进程开始执行新的程序。这两个函数用于执行指定的命令并完全替换进程的执行环境。例如:
```c
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t child_pid = fork(); // 创建子进程
if (child_pid == 0) { // 如果是子进程
execl("/bin/sleep", "sleep", "1", NULL); // 执行1秒命令
} else if (child_pid > 0) { // 父进程
wait(NULL); // 等待子进程结束
printf("child ended, father ending.\n"); // 子进程退出后,打印信息
} else { // fork失败的情况
perror("fork failed");
return 1;
}
return 0;
}
```
在这个例子中,父进程调用`waitpid(-1, NULL, WUNTRACED)`来阻塞,直到子进程结束。当子进程执行完`sleep 1`命令后,它会被系统终止,然后父进程继续运行并打印出提示。
- 用fork()创建一个子进程。 -子进程用execl或execve执行ls命令。 - 父进程调用waitpid函数等待子进程结束后,打印“child ended, father ending”,后结束进程。
在Unix/Linux系统编程中,可以使用`fork()`函数来创建一个新的进程(子进程),它会复制当前进程的所有状态,包括内存映射、打开文件描述符等。以下是步骤:
1. **使用`fork()`创建子进程**:
```c
#include <unistd.h>
int pid = fork(); // fork操作
if (pid == 0) { // 子进程
// 在这里执行后续操作,如设置工作目录、清理环境变量等
} else if (pid > 0) { // 父进程
// 子进程ID保存在pid变量中
} else {
perror("Fork failed"); // 如果fork失败,打印错误信息
exit(EXIT_FAILURE);
}
```
2. **子进程使用`execl`或`execve`执行ls命令**:
在子进程中,通常会替换掉原来的程序入口点,例如使用`execl`或其更安全版本`execve`执行其他程序,比如`ls`:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
if (pid == 0) {
execlp("ls", "ls", "-l", NULL); // 执行ls -l命令
perror("Failed to execute ls");
_exit(EXIT_FAILURE); // 使用_exit而非exit来避免影响父进程
}
```
3. **父进程等待子进程结束并打印消息**:
父进程调用`waitpid`等待子进程结束,然后继续执行:
```c
while (true) {
int status;
waitpid(pid, &status, 0); // 等待子进程结束
if (WIFEXITED(status)) {
printf("child ended, father ending\n");
break; // 子进程已正常退出,父进程结束
} else if (WIFSIGNALED(status)) {
printf("Child process terminated by signal %d\n", WTERMSIG(status));
} else {
printf("Unknown termination state for child.\n");
}
}
exit(0); // 父进程结束
```
阅读全文