使用 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
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