Linux 中的 fork、exec、wait 和 exit 系统调用解释Linux 中的 fork、exec、wait 和 exit 系统调用解释Linux 中的 fork、exec、wait 和 exit 系统调用解释Linux 中的 fork、exec、wait 和 exit 系统调用解释
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

Linux 中的 fork、exec、wait 和 exit 系统调用解释

可以单次、多次或同时执行的指令和数据序列称为程序。而过程就是这样的程序的执行。所以这些进程可以运行很多程序。在同一个进程中,操作系统可以加载不同的程序。重用的进程状态(例如当前目录、权限、文件句柄等)由新程序继承。这些事情与 fork()、exec()、wait() 和 exit() 等系统调用在同一级别完成。

在本文中,我们将通过示例和用例详细讨论 Linux 系统调用 fork()、exec()、wait() 和 exit()。

叉()

fork() 是 Linux/Unix 系统中非常特殊且有用的系统调用之一。进程使用它来创建作为自身副本的进程。在此类系统调用的帮助下,父进程可以创建子进程。直到子进程执行完毕,父进程才会被挂起。

fork() 的一些要点如下。

  • 父进程将获取非零值的子进程ID。
  • 零值返回给孩子。
  • 如果在创建子进程时出现任何系统或硬件错误,则 -1 将返回给 fork()。
  • 子进程获得的唯一进程ID,与任何现有进程组的ID都不匹配。

为了详细说明 fork(),我们举一个例子来阐明 fork() 的概念。

sudo vim fork.c

这是复制/粘贴它的代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int main(int argc, char **argv)
{
pid_t pid;
pid = fork();
if(pid==0)
{
printf("It is the child process and pid is %d\n",getpid());
exit(0);
}
else if(pid > 0)
{
printf("It is the parent process and pid is %d\n",getpid());
}
else
{
printf("Error while forking\n");
exit(EXIT_FAILURE);
}
return 0;
}

输出:

$make fork

运行脚本,我们得到如下截图所示的结果。

./fork

执行()

exec() 就是这样一个系统调用,它通过用新的进程映像替换当前进程映像来运行。然而,原来的进程仍然是一个新进程,但新进程替换了头数据、堆栈数据等。它通过将程序加载到当前进程空间来从入口点运行程序。

为了更详细地说明,让我们举一个例子,如下所示。

sudo vim exec.c

这是代码:

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

main(void) {
  pid_t pid = 0;
  int status;
  pid = fork();

if (pid == 0) {
  printf("I am the child.");
  execl("/bin/ls", "ls", "-l", "/home/ubuntu/", (char *) 0);
  perror("In exec(): ");
}

if (pid > 0) {
  printf("I am the parent, and the child is %d.\n", pid);
  pid = wait(&status);
  printf("End of process %d: ", pid);

  if (WIFEXITED(status)) {
    printf("The process ended with exit(%d).\n", WEXITSTATUS(status));
  }

  if (WIFSIGNALED(status)) {
    printf("The process ended with kill -%d.\n", WTERMSIG(status));
  }
}

if (pid < 0) {
  perror("In fork():");
}

exit(0);
}

输出:

make exec

运行脚本,我们得到如下截图所示的结果。

./exec

等待()

与 fork 的情况一样,子进程被创建并执行,但父进程被挂起,直到子进程执行。在这种情况下,由于父进程的挂起,wait()系统调用被自动激活。子进程结束执行后,父进程再次获得控制权。

为了详细说明 wait(),我们举一个例子来阐明 wait() 系统调用。

sudo vim wait.c

这是代码示例:

#include<stdio.h> // printf()
#include<stdlib.h> // exit()
#include<sys/types.h> // pid_t
#include<sys/wait.h> // wait()
#include<unistd.h> // fork

int main(int argc, char **argv)
{

pid_t pid;
pid = fork();

if(pid==0)

{
printf("It is the child process and pid is %d\n",getpid());

int i=0;
for(i=0;i<8;i++)
{
printf("%d\n",i);
}

exit(0);

}
else if(pid > 0)
{

printf("It is the parent process and pid is %d\n",getpid());

int status;
wait(&status);
printf("Child is reaped\n");
}

else
{

printf("Error in forking..\n");
exit(EXIT_FAILURE);

}

return 0;

}

输出:

make wait

运行脚本,我们得到如下截图所示的结果。

./wait

出口()

exit() 就是这样一个函数或用于终止进程的系统调用之一。该系统调用定义了线程执行完成,特别是在多线程环境的情况下。为了将来参考,捕获进程的状态。

使用exit()系统调用后,操作系统会检索进程中使用的所有资源,然后终止进程。系统调用Exit()相当于exit()。

概要

#include <unistd.h>
void _exit(int status);
#include <stdlib.h>
void _Exit(int status);

你可以在上面的fork()、wait()的例子中看到exit()函数的使用。使用 exit() 系统调用来终止进程。

结论

在本文中,我们通过一些示例详细学习了 fork()、exec()、wait() 和 exit() 系统调用。有关更多详细信息,请尝试使用这些系统调用运行程序并查看结果。谢谢你!

©2015-2025 艾丽卡 support@alaica.com