fork()和exec()的区别

yizhihongxing

fork()exec()的区别

在Linux系统中,fork()exec()是两个常用的系统调用,它们都与进程有关。但是它们的用途是不同的,这里详细讲解两者的区别。

fork()

fork()的作用是创建一个新的进程,新进程是原进程的副本,这个新进程被称为子进程。子进程具有与父进程(即原进程)完全相同的代码和数据,但是其运行状态和内存空间都是独立的,即父子进程之间不共享内存空间。

下面是一个简单的示例,展示了fork()的基本使用方法:

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

int main() {
   pid_t pid;
   int x = 1;

   pid = fork();

   if (pid == 0) {
      x++;
      printf("x in child process: %d\n", x); // 子进程中的 x
   }
   else {
      x--;
      printf("x in parent process: %d\n", x); // 父进程中的 x
   }
   return 0;
}

输出如下:

x in child process: 2
x in parent process: 0

在示例中,fork()创建了一个子进程。子进程执行了x++操作,x的值变为了2,而在父进程中x--操作使得x的值变为了0。

exec()

exec()的作用是在当前进程中执行一个新的程序,取代当前进程的数据和代码。也就是说,exec()调用之后,原来进程的代码和数据都被新的程序的代码和数据所取代。

下面是一个简单的示例,展示了exec()的基本使用方法:

#include<unistd.h>

int main() {
   char *argv[2];
   argv[0] = "/bin/ls"; // 为 ls 命令的绝对路径
   argv[1] = NULL; // 参数列表必须以 NULL 结束 

   execv("/bin/ls", argv);
   return 0;
}

这个程序调用了execv()函数,用/bin/ls作为参数来执行ls命令。执行该程序,将输出当前目录下的文件列表。

区别

fork()exec()一般一起使用,而且是顺序执行。调用fork()创建子进程后,一般立即调用exec()加载新的程序运行。但fork()exec()的区别在于它们的目的和作用不同:

  • fork()的作用是创建一个新的进程,与父进程的代码和数据相同,但运行状态和内存空间互不干扰。
  • exec()的作用是在当前进程中执行新程序的代码和数据,原来的进程被新程序取代。

在"fork()"和"exec()"的典型用法中,父进程调用"fork()"创建一个子进程,然后父进程通过子进程中的"exec()"函数来加载一个新的进程映像,使子进程成为一个新进程,从而执行由父进程所指定的程序。下面给出一个例子:

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

#define MAXLINE 1024

int main()
{
    char buf[MAXLINE];
    pid_t pid;
    int status;

    printf("%% "); /* print prompt (printf requires %% to print %) */
    while (fgets(buf, MAXLINE, stdin) != NULL) {
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = '\0';

        if ((pid = fork()) < 0) {
            printf("fork error");
            continue;
        } else if (pid == 0) { /* child */
            execlp(buf, buf, (char *) 0);
            printf("couldn’t execute: %s", buf);
            exit(127);
        }

        /* parent */
        if ((pid = waitpid(pid, &status, 0)) < 0)
            printf("waitpid error");
        printf("%% ");
    }
    exit(0);
}

这个程序通过fgets读入命令行输入,调用fork()创建一个新进程,子进程中调用execlp()函数合适地加载新的程序并执行,父进程则等待新建子进程结束并给出shell提示。这里 exec()是与 fork()配合使用的常用方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:fork()和exec()的区别 - Python技术站

(0)
上一篇 2023年5月10日
下一篇 2023年5月10日

相关文章

  • golang如何自定义json序列化应用详解

    自定义 JSON 序列化是 Golang 开发中非常有用的技术。 通过自定义序列化规则,我们可以将 Golang 程序数据结构转为 JSON 字符串或者将 JSON 字符串转为 Golang 数据结构,使得数据交互操作更加简单方便。本文将详细介绍如何在Golang中自定义JSON 序列化。 1.自定义JSON序列化 1.1 json.Marshal() 要实…

    C 2023年5月23日
    00
  • C语言代码实现简单三子棋游戏

    C语言代码实现简单三子棋游戏 简介 三子棋是一种经典的策略游戏,在游戏中两位玩家轮流放置棋子,直到有一方在棋盘上形成连续的三枚棋子为止。由于其简单而有趣,常被用于讲解人工智能、算法等知识点。本文将介绍如何使用C语言编写一个简单的三子棋游戏。 准备工作 在开始编码前,需要先准备好C语言的开发环境。推荐使用Visual Studio Code和MinGW来进行开…

    C 2023年5月23日
    00
  • iOS中多线程的经典崩溃总结大全

    很高兴听到您对iOS多线程崩溃总结的攻略感兴趣。下面我将为您提供详细的讲解。 引言 在iOS开发过程中,多线程是常见的技术,它允许我们运行多个任务并发执行,提升了应用程序的性能。但是多线程编程难度大,容易造成各种崩溃。在iOS中,多线程崩溃主要有以下几种: EXC_BAD_ACCESS错误:当访问不属于该线程的内存地址时会引发EXC_BAD_ACCESS崩溃…

    C 2023年5月22日
    00
  • 详解C++中的ANSI与Unicode和UTF8三种字符编码基本原理与相互转换

    下面是详解C++中的ANSI与Unicode和UTF8三种字符编码基本原理与相互转换的攻略。 一、字符编码的概念 字符编码是将字符集中的每个字符映射到某个二进制值的一种方法。常见的字符编码方式包括ASCII、ANSI、Unicode和UTF-8等。 ANSI编码指的是使用单字节表示每个字符的编码方式,它的编码范围是0-127,这种编码方式主要在早期的计算机和…

    C 2023年5月23日
    00
  • 用C语言实现猜数字游戏

    用C语言实现猜数字游戏完整攻略 1. 游戏规则 本猜数字游戏的规则非常简单,系统在1到100之间随机生成一个数字,然后玩家通过输入进行猜测,如果猜中则游戏胜利,若猜测的数字小于或大于目标数字,则系统会提示玩家重新猜测。 2. 程序实现 (1)首先我们需要定义一个目标数字,该数字需要随机生成。使用rand()函数可以生成一个随机数,我们通过加上1的操作让生成的…

    C 2023年5月23日
    00
  • PHP错误处理函数

    当 PHP 程序出错时,可以通过使用 PHP 错误处理机制来捕获并处理错误,PHP 为我们提供了一系列的错误处理函数来实现这一功能: 错误类型 PHP 内置了多种类型的错误,下面来简单介绍一下: E_ERROR 表示严重的错误,程序无法恢复运行,例如访问一个不存在的方法或函数 E_WARNING 表示警告信息,程序可以继续运行,但可能出现问题,例如访问一个未…

    C 2023年5月23日
    00
  • C语言返回动态分配内存的地址

    C语言中,返回动态分配内存的地址通常使用指针类型函数实现。在这种情况下,C语言程序需要使用malloc()等函数手动分配内存,并返回指向分配内存空间的指针。以下是如何返回动态分配内存的地址的完整使用攻略。 步骤1:使用malloc()函数分配内存空间 在C语言中,使用malloc()函数可以手动分配内存空间。该函数需要一个整数作为参数,指定需要分配的内存空间…

    C 2023年5月9日
    00
  • C++隐式转换问题分析及解决办法

    C++隐式转换问题分析及解决办法 背景 C++是一门强类型语言,变量必须先定义类型才能使用,这样可以提高代码的可靠性和执行效率。但在一些情况下,C++的强类型编程方式反而降低了编码的便利性和灵活性。因此,C++提供了隐式类型转换(implicit type conversion)机制,可以方便地将一种类型的变量转换成另一种类型的变量,这也是C++语言的特性之…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部