【linuxC语言】vfork、wait与waitpid函数

发布于:2024-05-08 ⋅ 阅读:(29) ⋅ 点赞:(0)


前言

在Linux系统编程中,vfork()、wait() 和 waitpid() 函数是处理进程管理和控制流的重要工具。这些函数允许我们创建新进程、等待子进程结束并获取其退出状态,从而实现进程间的协作和管理。


一、函数使用

1.1 vfork

原型:

#include <unistd.h>
pid_t vfork(void);

作用:
vfork() 函数创建一个新进程,新进程是调用进程的一个副本,但是在子进程调用 exec() 或 _exit() 之前,子进程执行期间会暂停父进程的执行,因为子进程共享父进程的地址空间。与 fork() 不同的是,vfork() 函数保证子进程先运行,且父子进程共享地址空间,直到子进程调用了 exec() 或 _exit()。
参数:
无参数。
返回值:
如果是子进程,返回0。
如果是父进程,返回子进程的进程ID。
如果发生错误,则返回-1。

1.2 wait

原型:

#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);

作用:
wait() 函数用于等待任何一个子进程结束,并获取其退出状态。调用 wait() 函数会阻塞当前进程,直到任何一个子进程退出为止。
参数:
status:用于存储子进程的退出状态信息的整型指针。
返回值:
如果成功等待到一个子进程结束,返回子进程的进程ID。
如果没有子进程,返回-1,并且设置 errno 为 ECHILD。
如果发生错误,则返回-1。

1.3 waitpid

原型:

#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);

作用:
waitpid() 函数提供了更灵活的等待子进程结束的方式。它允许指定要等待的特定子进程的进程ID,并可以选择是否阻塞当前进程。
参数:
pid:指定要等待的子进程的进程ID,可以是:
< -1:等待进程组ID等于 pid 的任一子进程。
-1:等待任一子进程,类似于 wait()。
0:等待与调用进程同一进程组ID的任一子进程。
>0:等待进程ID等于 pid 的子进程。

status:用于存储子进程的退出状态信息的整型指针。
options:用于指定额外选项的整型参数。
返回值:
如果成功等待到一个子进程结束,返回子进程的进程ID。
如果没有子进程,返回0,并且不设置 errno。
如果发生错误,则返回-1,并设置 errno。

二、示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
    pid_t pid;
    int status;

    printf("Before vfork\n");

    pid = vfork();

    if (pid == -1) {
        perror("vfork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // Child process
        printf("Child process executing\n");
        sleep(2); // Simulate some work
        printf("Child process exiting\n");
        _exit(EXIT_SUCCESS); // Ensure to exit from child process
    } else { // Parent process
        printf("Parent process executing\n");
        if (waitpid(pid, &status, 0) == -1) {
            perror("waitpid");
            exit(EXIT_FAILURE);
        }
        printf("Parent process continues\n");
    }

    return 0;
}

在这里插入图片描述


总结

在本文中,我们探讨了 vfork()、wait() 和 waitpid() 函数在Linux C语言编程中的应用。

vfork() 函数类似于 fork(),但是与 fork() 不同的是,它在子进程中共享父进程的地址空间,这样可以减少资源消耗。但需要注意的是,在子进程调用 exec() 或 _exit() 之前,父进程会被阻塞,直到子进程结束或调用了其中一个函数。
wait() 函数用于等待任何一个子进程结束,并获取其退出状态。调用 wait() 函数会阻塞当前进程,直到任何一个子进程退出为止。这有助于避免产生僵尸进程,保持系统的稳定性和性能。
waitpid() 函数提供了比 wait() 更加灵活的等待子进程退出的方法。它允许我们指定要等待的特定子进程的进程ID,并可以选择是否阻塞当前进程。这使得我们可以对子进程进行更精确的控制和管理。
综上所述,vfork()、wait() 和 waitpid() 函数在Linux C语言编程中扮演着重要角色,为进程管理和控制提供了强大的工具,使得我们能够更好地管理系统资源,确保程序的正确性和稳定性。