• 正文
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard-进程的基本操作之进程等待waitpid

05/09 16:55
202
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

waitpid()提供了更灵活的选项,允许父进程等待特定的子进程终止,或非阻塞地查询子进程状态,进一步增强了进程管理的灵活性。比如可以指定等待某个pid的子进程、提供一个非阻塞版本的wait()功能等,这对处理多个子进程的情况更加友好。

1.头文件

#include <sys/types.h>

#include <sys/wait.h>

2.函数原型

pid_t waitpid(pid_t pid, int *wstatus, int options);

3.参数

pid:参数的取值

如果pid小于-1:等待任何子进程,其进程组 ID 等于 -pid 的绝对值。

如果pid等于-1:等待任何子进程(与 wait() 的行为相同)。

如果pid等于0:等待任何子进程,其进程组 ID 等于调用进程的进程组 ID。

如果pid大于0:等待指定 PID 的子进程。

wstatus:指向一个整型变量的指针,用于存储子进程的退出状态。如果不需要,可以传 NULL。

options:可选的标志位,通常为 0表示使用默认的阻塞行为,即父进程会阻塞,直到指定的子进程结束,并返回该子进程的状态。常见的其他选项:

WNOHANG:非阻塞模式。如果子进程没有结束,立即返回0。如果子进程已经终止运行,则立即返回该子进程的进程号与状态信息。

WUNTRACED:返回被暂停的子进程状态。

WCONTINUED:如果子进程被继续执行,返回状态。

4.返回值

成功时,返回结束的子进程的 PID。如果没有符合条件的子进程,返回 0(在非阻塞模式下),或者 -1(在阻塞模式下),并设置 errno。

5.示例:使用waitpid()函数回收指定进程资源

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

int main() {

pid_t pid1 = fork(); // 创建第一个子进程

if (pid1 < 0) {

perror("fork failed");

exit(EXIT_FAILURE);

} else if (pid1 == 0) {

// 第一个子进程

printf("First child process (PID: %d) is running...\n", getpid());

sleep(2); // 模拟工作

exit(1); // 返回退出码1

}

pid_t pid2 = fork(); // 创建第二个子进程

if (pid2 < 0) {

perror("fork failed");

exit(EXIT_FAILURE);

} else if (pid2 == 0) {

// 第二个子进程

printf("Second child process (PID: %d) is running...\n", getpid());

sleep(3); // 模拟工作

exit(2); // 返回退出码2

}

// 父进程等待第一个子进程

int status;

pid_t result1 = waitpid(pid1, &status, 0); // 阻塞等待第一个子进程

if (result1 == -1) {

perror("waitpid failed");

exit(EXIT_FAILURE);

}

printf("First child terminated with PID: %d\n", result1);

if (WIFEXITED(status)) {

printf("First child exited with status %d\n", WEXITSTATUS(status));

}

// 使用非阻塞方式等待第二个子进程

pid_t result2 = waitpid(pid2, &status, WNOHANG);

if (result2 == 0) {

printf("Second child is still running...\n");

} else if (result2 == -1) {

perror("waitpid failed");

} else {

printf("Second child terminated with PID: %d\n", result2);

if (WIFEXITED(status)) {

printf("Second child exited with status %d\n", WEXITSTATUS(status));

}

}

// 等待所有子进程结束

while ((result1 = waitpid(-1, &status, WNOHANG)) > 0) {

printf("Processed child with PID: %d\n", result1);

if (WIFEXITED(status)) {

printf("Child exited with status %d\n", WEXITSTATUS(status));

} else if (WIFSTOPPED(status)) {

printf("Child is stopped by signal %d\n", WSTOPSIG(status));

} else if (WIFCONTINUED(status)) {

printf("Child has been continued.\n");

}

}

return 0;

}

6.运行结果

First child process (PID: 200850) is running...

Second child process (PID: 200851) is running...

First child terminated with PID: 200850

First child exited with status 1

Second child is still running...

7.代码解析

父进程创建两个子进程,分别在模拟工作后退出,并返回不同的退出码。然后使用 waitpid(pid1, &status, 0) 阻塞等待第一个子进程结束,并获取其退出状态,通过exit程序退出之后就不会接着执行后面的程序了。使用 waitpid(pid2, &status, WNOHANG) 非阻塞方式检查第二个子进程的状态,如果仍在运行,父进程会立即返回。最后,父进程通过 waitpid(-1, &status, WNOHANG) 循环等待所有子进程结束,处理每个子进程的状态。

相关推荐