fork() 和 exec()的区别

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

fork()

pid_t pid = fork(); 

fork()通过复制调用进程来创建一个新进程,新进程称为子进程,是调用进程(称为父进程)的完全副本,但以下情况除外:

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

fork()的返回值
成功时,父进程返回子进程的PID,子进程返回0。 失败时,在父进程中返回 -1,不创建子进程,并适当设置 errno

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() 的情况下,父进程和子进程同时执行,而控制永远不会返回到原始程序,除非出现 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 occured     printf("can't fork, error occuredn");     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 = %un",getpid());     // Here It will return Parent of child Process means Parent process it self     printf("parent of child process, pid = %un",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 occured.     // 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 = %un",getppid());     printf("parent process, pid = %un",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 successfuln");              else if (WIFEXITED(status) && WEXITSTATUS(status)) {                 if (WEXITSTATUS(status) == 127) {                      // execv failed                     printf("execv failedn");                 }                 else                     printf("program terminated normally,"/n                    " but returned a non-zero statusn");                             }             else             printf("program didn't terminate normallyn");                     }         else {         // waitpid() failed         printf("waitpid() failedn");         }     exit(0); } return 0; } 

运行结果:

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

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/264169.html

(0)
上一篇 2022年6月7日 00:42
下一篇 2022年6月7日 00:43

相关推荐

发表回复

登录后才能评论