fork()和exec()的区别

来源:这里教程网 时间:2026-02-16 13:49:16 作者:

fork()和exec()的区别

每个应用程序(程序)都是通过进程来执行的,进程是程序的一个运行实例。进程是通过不同的系统调用创建的,最常用的是fork()和exec()

fork()

pid_t pid = fork();

fork()通过复制调用进程来创建一个新进程,这个新进程被称为子进程,是调用进程的精确副本,被称为父进程,除了以下情况:

    子进程有自己唯一的进程ID,并且这个PID与任何现有进程组的ID不匹配。子进程的父进程ID与父进程ID相同。子进程不会继承父进程的内存锁和信号量调整。子进程不会从父进程继承未完成的异步I/O操作,也不会从父进程继承任何异步I/O上下文。

fork()如果成功,子进程的PID在父进程中返回,子进程返回0。失败时,父进程中返回-1,不创建子进程,并适当地设置errno。关于fork系统调用的详细文章

exec()

exec()系列函数用一个新的进程映像替换当前进程映像。它将程序加载到当前进程空间中,并从入口点运行它。exec()家族由以下函数组成,我在下面的C程序中实现了execv(),您可以尝试休息作为练习

int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg, ...,                                char * const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[],                               char *const envp[]);

fork与exec

Fork启动一个新进程,它是调用它的进程的副本,而exec用另一个(不同的)进程映像替换当前进程映像。在fork()的情况下,父进程和子进程会同时执行,而Control永远不会返回到原始程序,除非出现exec()错误。
// C program to illustrate  use of fork() &// exec() system call for process creation #include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <stdlib.h>#include <errno.h> #include <sys/wait.h> int main(){   pid_t  pid;   int ret = 1;   int status;   pid = fork();    if (pid == -1){       // pid == -1 means error occurred      printf("can't fork, error occurred\n");      exit(EXIT_FAILURE);   }   else if (pid == 0){       // pid == 0 means child process created      // getpid() returns process id of calling process      // Here It will return process id of child process      printf("child process, pid = %u\n",getpid());      // Here It will return Parent of child Process means Parent process it self      printf("parent of child process, pid = %u\n",getppid());       // the argv list first argument should point to       // filename associated with file being executed      // the array pointer must be terminated by NULL      // pointer      char * argv_list[] = {"ls","-lart","/home",NULL};       // the execv() only return if error occurred.      // The return value is -1      execv("ls",argv_list);      exit(0);   }   else{      // a positive number is returned for the pid of      // parent process      // getppid() returns process id of parent of      // calling process// Here It will return parent of parent process's ID      printf("Parent Of parent process, pid = %u\n",getppid());      printf("parent process, pid = %u\n",getpid());         // the parent process calls waitpid() on the child        // waitpid() system call suspends execution of        // calling process until a child specified by pid        // argument has changed state        // see wait() man page for all the flags or options        // used here        if (waitpid(pid, &status, 0) > 0) {                         if (WIFEXITED(status) && !WEXITSTATUS(status))              printf("program execution successful\n");                         else if (WIFEXITED(status) && WEXITSTATUS(status)) {                if (WEXITSTATUS(status) == 127) {                     // execv failed                    printf("execv failed\n");                }                else                    printf("program terminated normally,"                       " but returned a non-zero status\n");                           }            else               printf("program didn't terminate normally\n");                   }        else {           // waitpid() failed           printf("waitpid() failed\n");        }      exit(0);   }   return 0;}

输出:

parent process, pid = 11523child process, pid = 14188Program execution successful

让我们用表格的形式来看看它们的区别:

序号fork ()exec ()
1.它是用C语言编写的系统调用它是操作系统的一个系统调用
2.它用于创建一个新流程Exec()运行可执行文件
3.它的返回值是一个整型它不会创建新的流程
4.它不接受任何参数。这里,Process标识符没有改变
5.它可以返回三种类型的整数值在exec()中,进程的机器码、数据、堆和堆栈被新程序取代。

相关推荐