使用 C 语言中的 fork 函数

Jinku Hu 2023年1月30日 2021年2月28日
  1. 使用 fork 函数在 C 语言中创建一个新的进程
  2. 在 C 语言中使用 exec 函数之一在子进程中执行新程序
使用 C 语言中的 fork 函数

本文将介绍几种在 C 语言中使用 fork 函数的方法。

使用 fork 函数在 C 语言中创建一个新的进程

fork 函数用于创建一个新的进程,代表调用者进程的重复。需要注意的是,调用进程按惯例被称为父进程,新创建的进程-子进程。尽管我们在上面提到子进程是父进程的重复,但还是有一些区别,比如子进程有自己唯一的 PID(关于区别的完整细节在 fork 手册中列出)。

在下面的例子中,我们实现了一个简单的场景,即使用 fork 来并发执行两个进程。第一个 if 语句检查是否返回错误代码,只有在 fork 成功的情况下才继续执行。下一个 if 语句演示了如何组织代码由并发进程执行。

与其他函数相比,fork 调用有点独特,因为它成功后会返回两次-在父进程和子进程中-在父进程中返回子进程的 PID,在子进程中返回 0 值。需要注意的是,我们相应地指定了循环的条件,以区分进程的不同代码路径。

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

int main(void) {

    pid_t c_pid = fork();
    if (c_pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (c_pid == 0) {
        printf("printed from child process - %d\n", getpid());
        exit(EXIT_SUCCESS);
    } else {
        printf("printed from parent process - %d\n", getpid());
        wait(NULL);
    }

    exit(EXIT_SUCCESS);
}

输出:

printed from parent process - 8485
printed from child process - 8486

在 C 语言中使用 exec 函数之一在子进程中执行新程序

使用 fork 函数的常见情况之一是在子进程中执行一个新的程序,这可以通过在其中添加一个 exec 函数来实现。在这种情况下,我们实现了一个名为 spawnChild 的单独函数,它可以创建一个新的进程,然后调用 execvp 来执行给定的程序。我们选择了一个广泛使用的命令行程序-top 在子进程中执行。需要注意的是,父进程可以选择使用 waitpid 来等待子进程的状态变化。

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

pid_t spawnChild(const char* program, char** arg_list)
{
    pid_t ch_pid = fork();
    if (ch_pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (ch_pid == 0) {
        execvp(program, arg_list);
        perror("execve");
        exit(EXIT_FAILURE);
    } else {
        printf("spawned child with pid - %d\n", ch_pid);
        return ch_pid;
    }
}

int main(void) {
    int ret;
    const char *args[] = { "top", NULL, NULL };

    pid_t child;
    int wstatus;

    child = spawnChild("top", args);

    if (waitpid(child, &wstatus, WUNTRACED | WCONTINUED) == -1) {
        perror("waitpid");
        exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
}

输出:

printed from child process - 8486
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相关文章 - C Process