Linux手账—exec和fork

简介: 本文介绍了Linux系统中进程控制的核心功能——`fork`和`exec`系列函数。`fork`用于创建新进程(子进程),继承父进程的资源但拥有独立的地址空间;`exec`系列函数则在当前进程中执行新程序,替换原有地址空间。文章详细解析了这些函数的基本概念、用法及工作原理,强调了它们在多进程编程中的重要性。

前言

在操作系统中,进程控制和程序执行是核心功能。fork 和 exec 系列函数为此提供了强大的工具。fork 用于创建一个新进程(子进程),而 exec 系列函数则用于在当前进程中执行新程序,替换其代码段。本文旨在简要介绍这两个函数的基本概念、用途和工作原理。

evec

包含的头文件:

#include <unistd.h>:这个头文件包含了POSIX操作系统API的函数原型,如文件操作、进程控制、目录操作等。在这里,它主要是为了使用exec系列的函数。


外部变量:

extern char **environ;:这行代码声明了一个外部变量environ,它是一个指向字符指针数组的指针。这个数组包含了当前进程的环境变量,每个元素都是一个指向以null结尾的字符串的指针。这个数组以NULL结尾。


函数原型:

代码中列出了多个exec系列的函数原型,但有一些拼写错误和格式问题。正确的函数名和参数应该如下:注意:


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[]);


int execve(const char *filename, char *const argv[], char *const envp[]);


exel应为execl。


exele应为execle,且参数列表中的逗号使用有误,应去掉多余的逗号。


execv和execvp的函数原型在图片中基本正确,但execvp的参数列表中的逗号位置不影响其意义,只是格式上的小瑕疵。


execvpe和execve的函数原型在图片中同样存在格式上的问题,主要是多余的逗号,但核心意思正确。


NULL指针:

代码中提到了NULL,但在给出的文本中,NULL被误写为NOLL。在C语言中,NULL用于表示空指针。


函数功能:

这些exec系列的函数都用于在当前进程中执行一个新的程序。它们会替换当前进程的地址空间(代码、数据、堆栈等)为新程序的地址空间。


不同的exec函数提供了不同的方式来指定要执行的程序、传递命令行参数以及设置环境变量。


int execl(const char *path, const char *arg, ...);


execl函数使用给定的路径名path来执行一个程序。


第二个参数arg是传递给新程序的第一个命令行参数(通常是程序的名称)。


后续参数是可变数量的命令行参数,列表必须以NULL结尾。


int execlp(const char *file, const char *arg, ...);


execlp函数类似于execl,但它使用PATH环境变量来查找要执行的程序。


file参数是程序名,而不是路径名。


其余参数与execl相同。


int execle(const char *path, const char *arg, ..., char *const envp[]);


execle函数与execl类似,但它允许用户指定一个新的环境变量数组envp。


envp是一个以NULL结尾的字符指针数组,每个元素都是一个指向环境变量的指针。


其余参数与execl相同。


int execv(const char *path, char *const argv[]);


execv函数使用给定的路径名path来执行一个程序。


argv是一个指向以NULL结尾的字符指针数组的指针,该数组包含要传递给新程序的命令行参数。


argv[0]通常是程序的名称。


int execvp(const char *file, char *const argv[]);


execvp函数类似于execv,但它使用PATH环境变量来查找要执行的程序。


file参数是程序名,而不是路径名。


argv参数与execv相同。


int execvpe(const char *file, char *const argv[], char *const envp[]);


execvpe函数结合了execvp和execle的特点。


它使用PATH环境变量来查找要执行的程序,并允许用户指定一个新的环境变量数组envp。


file和argv参数与execvp相同,envp参数与execle相同。


int execve(const char *filename, char *const argv[], char *const envp[]);


execve函数是最通用和最强大的exec函数。


它允许用户直接指定要执行的文件的名称filename、命令行参数数组argv和环境变量数组envp。


filename可以是绝对路径或相对路径。


fork

fork是Linux系统中的一个非常重要的系统调用,它用于创建一个新的进程。以下是关于fork命令的详细分析:


一、fork的基本功能

fork函数通过系统调用创建一个与原来进程几乎完全相同的进程,新创建的进程被称为子进程,而原进程被称为父进程。子进程会继承父进程的资源,包括代码、数据、堆栈、文件描述符、内存映射、信号处理等,但每个进程都会拥有自己独立的地址空间和堆栈。


二、fork的返回值

在父进程中,fork函数返回新创建的子进程的进程ID(PID)。

在子进程中,fork函数返回0。

如果创建进程失败,fork函数返回-1,并设置相应的errno值以指示错误类型。


三、fork的执行流程

当调用fork函数时,操作系统会为新的子进程分配资源,包括存储数据和代码的空间。

操作系统会把父进程的所有值都复制到新的子进程中,但某些值(如进程ID、父进程ID、返回地址等)在子进程中会被设置为新的值。

fork函数会返回两次:一次在父进程中返回子进程的PID,一次在子进程中返回0。因此,在调用fork函数后,需要判断返回值以确定当前是在父进程还是子进程中。


四、fork后的进程状态

父进程和子进程是并发执行的,它们的执行顺序是不确定的,这取决于操作系统的进程调度策略。

父进程和子进程之间的内存空间是独立的,它们不能直接共享变量和数据。如果需要在父子进程之间共享数据,可以使用共享内存、管道、消息队列等进程间通信(IPC)机制。

子进程会继承父进程的文件锁、信号处理器等状态,但也可以独立地修改这些状态。


总结

简而言之,fork 函数用于创建一个新进程,该进程是调用进程的副本(子进程)。子进程会继承父进程的资源,但拥有独立的地址空间和堆栈。而 exec 系列函数则用于在当前进程中执行新程序,替换其地址空间。这些函数为开发者提供了进程控制和程序执行的灵活性。通过 fork 和 exec,开发者可以实现多进程编程,提高程序的并发性和响应速度。同时,需要注意这些函数的返回值和执行流程,以及进程间的独立性和通信机制。


目录
相关文章
|
7天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
9天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1569 10
|
1月前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
14天前
|
存储 人工智能 开发工具
AI助理化繁为简,速取代码参数——使用python SDK 处理OSS存储的图片
只需要通过向AI助理提问的方式输入您的需求,即可瞬间获得核心流程代码及参数,缩短学习路径、提升开发效率。
1032 1
AI助理化繁为简,速取代码参数——使用python SDK 处理OSS存储的图片
|
14天前
|
人工智能 Serverless API
AI助理精准匹配,为您推荐方案——如何快速在网站上增加一个AI助手
通过向AI助理提问的方式,生成一个技术方案:在网站上增加一个AI助手,提供7*24的全天候服务,即时回答用户的问题和解决他们可能遇到的问题,无需等待人工客服上班,显著提升用户体验。
1000 4
|
13天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
796 27
|
1天前
|
人工智能 关系型数据库 Serverless
1024,致开发者们——希望和你一起用技术人独有的方式,庆祝你的主场
阿里云开发者社区推出“1024·云上见”程序员节专题活动,包括云上实操、开发者测评和征文三个分会场,提供14个实操活动、3个解决方案、3 个产品方案的测评及征文比赛,旨在帮助开发者提升技能、分享经验,共筑技术梦想。
425 44
|
7天前
|
并行计算 PyTorch TensorFlow
Ubuntu安装笔记(一):安装显卡驱动、cuda/cudnn、Anaconda、Pytorch、Tensorflow、Opencv、Visdom、FFMPEG、卸载一些不必要的预装软件
这篇文章是关于如何在Ubuntu操作系统上安装显卡驱动、CUDA、CUDNN、Anaconda、PyTorch、TensorFlow、OpenCV、FFMPEG以及卸载不必要的预装软件的详细指南。
494 3
|
2天前
|
移动开发 JavaScript 前端开发
💻揭秘!如何用 Vue 3 实现酷炫的色彩魔方游戏✨
本文分享了开发基于Canvas技术的小游戏"色彩魔方挑战"的完整过程。游戏旨在考验玩家的观察力和耐心,通过随机生成的颜色矩阵和一个变化点,玩家需在两幅画布中找出不同的颜色点。文章详细讲解了游戏的核心功能,包括随机颜色矩阵生成、点的闪烁提示、自定义配色方案等。此外,作者展示了使用Vue 3和TypeScript开发的代码实现,带领读者一步步深入了解游戏的逻辑与细节。
105 68
|
16天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
874 5