📅  最后修改于: 2023-12-03 14:41:18.852000             🧑  作者: Mango
fork()
和 exec()
之间的区别在 Unix/Linux 系统中,fork()
和 exec()
是两个非常重要的系统调用。
fork()
fork()
系统调用可以创建一个新的进程,这个新的进程是原进程的副本,也就是说,它继承了原进程的数据和代码段、堆和栈等资源。新进程有自己的进程 ID,与原进程的 ID 是不同的。同时,它有一个独立的地址空间,这个地址空间包含了原进程数据和代码的一份副本。
fork()
的返回值不同,如果返回 0,则表示当前进程是新创建出来的子进程;如果返回大于 0 的值,则表示当前进程是原来的父进程。两个进程的内存地址可以通过 getpid()
系统调用来获取。
#include<unistd.h>
pid_t fork(void);
exec()
exec()
系统调用可以用来替换当前进程的内存映像,也就是说,执行一个新的程序文件,并且将当前进程所占用的空间全部释放掉,替换成新的进程的地址空间。
在调用这个函数之前,你需要先用 fork()
创建一个新的进程,然后在这个新的进程中执行 exec()
函数。这个函数接受两个参数,第一个参数是新程序的路径名,第二个参数是一个数组,这个数组表示新程序的命令行参数。第一个参数是必须的,但是第二个参数可以为 NULL。如果要传入命令行参数,数组的最后一个元素必须为 NULL。
#include<unistd.h>
int execve(const char *filename, char *const argv[], char *const envp[]);
fork()
用于创建一个新的进程,而 exec()
用于执行一个新的程序文件。fork()
返回一个新的进程 ID,而 exec()
并不会返回。fork()
只能创建出新的副本进程,而它们之间并没有共享内存,也没有什么联系。而 exec()
可以重新启动一个新的进程,它可以继承上一个进程的环境变量和其他一些变量信息,就好像它们是一个整体一样。#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
pid_t pid;
char *const args[] = {"./hello", "world", NULL};
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
/* 子进程 */
if (execve(args[0], args, NULL) == -1) {
perror("execve");
exit(EXIT_FAILURE);
}
} else {
/* 父进程 */
printf("Parent process\n");
exit(EXIT_SUCCESS);
}
return 0;
}
这个程序创建了一个子进程,并在子进程中执行了另一个程序 hello
,这个程序把它的命令行参数打印出来。