首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

fork,wait和exec

fork,wait和exec fork系统调用 wait系统调用 exec系统调用 为什么要把fork和exec分开 ---- fork系统调用 1、子进程不会从 main()函数开始执行,而是直接从...但是,我们常常想运行不同的程序,exec()正好做这样的事 这个例子中,子进程调用 execvp()来运行字符计数程序 wc。...因此,它并没有创建新进程,而是直接将当前运行的程序(以前的 p3)替换为不同的运行程序(wc)。子进程执行 exec()之后,几乎就像p3.c 从未运行过一样。...fork和exec分开 在构建UNIX shell 的时候非常有用,因为这给了shell 在fork 之后exec 之前运行代码的机会,这些代码可以在运行新程序前改变环境,实现一些有趣的功能。...这样,即将运行的程序wc 的输出结果就被发送到该文件,而不是打印在屏幕上。

1K20

详谈 Linux进程控制(看这一篇就够了)

而且他们都运行到相同的地方。但每个进程都将可以开始他们自己的旅程。...✨2. fork函数的返回值 子进程返回0,父进程返回的是子进程的pid。 为什么有两个返回值, 因为fork之后是两个不同的进程, 而返回值也是给不同的进程。...一个进程要执行一个不同的程序, 例如子进程从fork返回后,调用exec函数。 ✨5. fork调用失败的原因 系统中有太多的进程。 实际用户的进程数量超过了限制。 三....进程程序替换 fork()之后, 父子各自执行父进程代码的一部分如果子进程想执行一个全新的程序呢? 进程的程序替换来完成这个功能!...argv[]); int execve(const char *path, char *const argv[], char *const envp[]); 2.1 函数解释 这些函数如果调用成功则加载新的程序从启动代码开始执行

12810
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【Linux】模拟实现一个shell

    就像这篇文章讲的那样,我们的程序中能够读取到我们输入的东西,所以为什么我们不能够利用这点来实现每次的命令行输入,将对应到进程替换成我们需要的进程,运行结束之后再退出来。...所以对于这个函数来说就是为了处理一开始得到的不是我们最终想要的结果。如果不知道原本是什么的话,其实简单说一下也就是从家目录到当前目录的所有的路径都在环境变量的cwd中。所以我们才需要进行额外的处理。...如果找不到符合条件的话,就返回NULL。 为什么就是需要我们去实现一个字符串分割为多个呢?...4、5、CheckBuildin函数 内建命令的特点就是不需要考虑当前环境或者是默认的配置的条件,在什么地方shell都能够运行出来相对于的结果。 对于现在的我来说我只认识两个内建命令。...4、6、ExecuteCommand函数 进程替换,那就是说在该函数中需要使用到fork()函数,并且还需要判断使用哪一个系统调用函数来确定传参条件。考虑之后还是使用execvp函数。

    12310

    【linux】进程等待与进程替换

    WIFSTOPPED(status): 判断子进程是否因信号停止。 返回非零值表示子进程被信号停止,可以通过 WSTOPSIG(status) 获取导致停止的信号编号。...当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。...*const argv[]); int execve(const char *path, char *const argv[], char *const envp[]); 这些函数如果调用成功则加载新的程序从启动代码开始执行...成功调用 execl 后**,原进程的代码和数据将被 ls 程序替换,原 main 函数之后的代码不会被执行**。...fork() 在父进程中返回子进程的 PID,在子进程中返回 0。 由于操作系统的调度策略,父进程和子进程之后的执行顺序是不确定的。

    7510

    Linux进程控制

    一.进程创建 fork()函数: 在进程概念这篇文章中,我们浅浅地了解了一下fork函数,它的功能是让父进程去创建一个子进程,并且有两个返回值,对应着父进程的返回值和子进程的返回值。...从main返回 2. 调用exit 第一种很好理解,我们的程序都是从main函数开始,最后由main函数的return 0来返回,终止程序。对于第二种,我们需要认识exit()函数。...char *const argv[]); 函数解释: 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。...所以我们回到上面的那个问题,为什么第二个printf没有执行? 答案就是:因为第二个printf是在execl之后的,在执行了execl后,第二个printf被覆盖掉了,所以也就没办法执行了。...由此,子进程的程序替换也不会影响到了父进程。

    2.4K30

    进程控制第二弹(进程程序替换)

    基本原理 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。...调用exec并不创建新进程,所以调用exec前后该进程的id并未改变 我们知道,进程=内核数据结构+代码数据 程序替换的本质是将当前进程的代码和数据进行替换。 替换的时候,会不会创建新的进程?...所以为什么上述现象中,原来的进程中printf("testexec end! ...\n"); 没有执行的原因是,调用execl函数后,去执行ls程序了,原来的代码和数据被替换了。...exec系列函数执行完毕后,后续的代码不见了,因为被替换了,因此没有机会去执行了。 不用关心exec系列函数的返回值,只要替换成功,就不会向后面执行;反之,一定是替换失败。...可执行程序testexecl从磁盘中加载到物理内存中。

    8710

    Linux:进程控制(二.详细讲解进程程序替换)

    这个函数的作用是在当前进程的上下文中启动一个新的程序,并替换当前进程的映像为新的程序映像。调用execl函数后,当前进程将停止执行,并由新的程序开始执行。...\n"); return 0; } 如果execl函数调用成功,那么它实际上不会返回,因为当前进程的映像已经被新程序替换。如果调用失败,它会返回-1,并设置全局变量errno以指示错误原因。...因为被替换掉了,这也是什么代码没有输出execl end的原因了 exec函数调用成功,那么它实际上不会有返回值;调用失败,它会返回-1 exec函数不会创建新的进程。...这个过程涉及将新程序的内容从磁盘加载到内存中,为进程提供执行所需的资源。...,它定义在 头文件中。

    22110

    【C++探索学习】第十九弹——进程替换:深入解析操作系统中的进程替换机制

    spm=1001.2014.3001.5482 前言: 在Linux操作系统中,进程替换(Process Replacement)是一个重要的概念,它允许程序通过系统调用用另一个程序替换当前进程的执行内容...需要注意的是,进程替换操作本身并不会改变进程的PID(进程ID)。也就是说,进程替换发生后,新的程序在执行时,进程ID仍然是原进程的PID。...运行结果: 3. exec系列函数的常见错误 尽管exec系列函数非常强大,但它们也有一些常见的错误,需要注意。 3.1 返回值与错误处理 exec系列函数调用成功时,不会返回控制权给调用者。...它们会替换当前进程的映像,新的程序开始执行。因此,如果exec调用成功,后面的代码将不会执行。...exec不会返回,如果你需要在exec失败时处理错误,必须在调用后检查返回值。 4. 总结 进程替换是Linux中一个非常重要的概念,exec系列函数提供了在运行时替换当前进程的能力。

    10110

    Linux-Copy On Write写时复制机制初探

    (函数族exec( )是一组函数的统称, 它包括了execl()、execlp()、execv()、execle()、execve()、execvp()等) fork fork是类Unix操作系统上创建进程的主要方法...); return 0; } 输出结果 我是子进程,由父进程fork出来 统计结果是: 1 我是父进程 统计结果是: 1 fork 函数会有两次返回 1) 将子进程的PID返回给父进程...---- 为什么有了COW? 早期的 Unix 在实现 fork 系统调用时,并没有使用该技术,创建新进程的开销很大。...现在Linux的fork()使用写时拷贝页来实现新进程的创建,它是一种可推迟甚至避免数据拷贝的技术,刚开始时内核并不会复制整个地址空间,而是让父子进程共享地址空间,只有在写时才复制地址空间,使得父子进程都拥有独立的地址空间...如果子进程不对内存空间进行写入操作的话,内存空间中的数据并不会复制给子进程,这样创建子进程的速度就很快 ,因为不用复制,直接引用父进程的物理空间 ,并且如果在fork函数返回之后,子进程第一时间exec

    3.6K10

    【Linux】进程控制

    进程常见退出方法: 从main函数return返回。...进程为什么要等待 1.父进程通过进程等待的方式,回收子进程资源 2.获取子进程退出信息 进程等待的方法 wait 返回值:成功返回被等待进程pid,失败返回-1。...当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 例程开始执行。...printf也是代码,在exec之后,exec执行完毕之后代码已经全部被覆盖,开始执行新的代码,所以第二个printf就无法执行了。...对于返回值问题: 这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回,和接下去的代码无关了。如果调用出错则返回-1,所以exec函数只有出错的返回值而没有成功的返回值。

    20030

    【Linux】从 fork() 到 exec():理解 Linux 进程程序替换的魔法

    在Linux或UNIX系统中,进程程序替换通常发生在一个进程通过fork()创建了子进程之后,子进程用exec()函数加载和执行另一个程序。...也就是说,进程程序替换就是在不改变进程的PID(进程ID)的情况下,用一个全新的程序来替换当前的内存空间和执行内容。...argv[]); int execve(const char* path,char* const argv[],char* const envp[]); 2.1 函数解释 这些函数如果调用成功则加载新的程序从启动代码开始执行...在程序的替换函数,通常不会让父进程去执行,而是交给子进程去执行,因为父进程还需要进行完成它的时,同时也防止替换的程序造成程序崩溃。...它常用于父进程通过 fork() 创建子进程后,子进程用 exec() 替换为新的程序来执行指定任务。 替换后的进程将完全抛弃原来的代码和数据,并开始执行新加载的程序。

    11010

    【Linux】Linux进程控制>进程创建&&进程终止&&进程等待&&进程程序替换

    fork代码后,内核做: 分配新的内存块和内核数据结构给子进程 将父进程部分数据结构内容拷贝至子进程 添加子进程到系统进程列表当中 fork返回,开始调度器调度 当一个进程调用fork之后,就有两个二进制代码相同的进程...而且它们都运行到相同的地方。...另一个after消息有28112打印的。注意到进程28112没有打印before,为什么呢?如下图所示: 所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。...当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。...其中时间从左向右。shell由标识为sh的方块代表,它随着时间的流逝从左向右移动。shell从用户读入字符串"ls"。

    16510

    Linux进程控制

    Linux进程简介 进程是操作系统中的一个重要概念,它是一个程序的一次执行过程,程序是进程的一种静态描述,系统中运行的每一个程序都是在它的进程中运行的。...新的进程不是被创建,而是被复制,或是从以前的进程复制而来。Linux中所有的进程都是由一个进程号为1的init进程衍生而来的。...pid = fork();之前,只有一个进程在执行代码,但在该语句之后,有两个进程在执行之后的代码,根据pid的不同执行不同的语句。...与一般情况不同,exec函数族执行成功后不会返回,因为调用进程实体,包括代码段、数据段和堆栈段都被新的内容取代,只是进程ID等一些表面上的信息仍保持原样。...exit()在调用之前要检查文件的打开情况,把文件缓冲区的内容写回文件;_exit()则直接使进程停止,清除其使用的内存空间,并销毁其在内核中的各种数据结构。

    2K30

    exec族

    这个一直没搞太明白,相识度高是一回事,不会用又是另一回事儿。 所以今天又温故了一遍: 为什么需要exec函数?...exec族函数可以直接把一个编译好的可执行程序直接加载运行。 有了exec族函数后,典型打父子进程程序是这样的:子进程需要运行的程序被单独编写、单独编译链接成一个可执行程序(hello)。...主进程为父进程,fork创建了子进程后在子进程中exec来执行hello,达到父子进程分别做不同程序同时(宏观上)运行的效果。...,出错返回-1....PATH变量查找子程序文件 e 函数传递指定参数envp,允许改变子进程的环境,无后缀e时,子进程使用当前程序的环境 下面我找到一些通俗易懂的栗子,算是让我明白了一点: #ifdef HAVE_CONFIG_H

    1.1K10

    【Linux系统编程】八、进程程序替换

    当进程调用一种 exec 函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行(也就是说替换后原进程后面的代码就被覆盖了,不会再被执行)。...(包括 envp[] 中也要以 NULL 结尾) 二、共同特性 调用成功则加载新的程序从启动代码开始执行,不再返回 调用出错则返回 -1 exec 函数 只有出错的返回值 而没有成功的返回值(因为成功调用的时候已经开始执行新程序...所以 exec 可以理解成一种特殊的加载器。 Ⅴ. 模拟实现一个简易的 shell 程序 ​ 用下图的时间轴来表示事件的发生次序。其中时间从左向右。...shell 由标识为 sh 的方块代表,它随着时间的流逝从左向右移动。shell 从用户读入字符串 "ls"。shell 建立一个新的进程,然后在那个进程中运行 ls 程序并等待那个进程结束。 ​...ls 指令,如果我们想要它每次打印的时候带上颜色,我们可以在一开始切割之前就判断是否为 ls ,是的话我们将第二个参数变成 --color=auto 这样子就能带上颜色了! ​

    4400

    【Linux】开始学习进程替换吧!

    —— 尾田荣一郎《海贼王》 开始学习进程替换吧 1 前言 通过学习进程替换,我们可以体会到多语言混搭的快乐,可以从C语言直接蹦到python ,也可以从c++里运行java代码。是不是很厉害!...),可是我执行的是我们的代码,怎么就运行了ls 这个程序呢?...当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 开始执行。 调用exec并不创建新进程,所以调用exec前后该进程的id并未改变 没有创建新进程!!!...exec* 就类似一个Linux 上的加载函数。 而且我们不用关心exec*函数的返回值,只要替换成功了,就不会向后运行(也就用不到它的返回值了),只要继续运行那一定就是替换失败了!!!...这样应该就可以运行ls命令还不会影响原本程序。

    9210

    初识Linux · 进程替换

    进程替换我们从如下几个点开始介绍,第一,直接看现象,第二,解释原理,第三,将代码改成多线程版本,第四,使用所有的替换函数,认识参数的含义。 废话不多说,直接进入主题。...我们不妨使用man手册查看一下: 输入: man exec 从文档里面我们可以看到进程替换的函数版本有这么多个,每个函数都有返回值,但是呢我们不必在意返回值,因为通过现象,我们看到了执行进程替换函数之后的代码都失效了...2 解释原理 首先我们要清楚一个问题,进程替换的全名不是进程替换,替换的不是进程,是程序,所以在进程程序替换的这个过程,本质上是没有创建新的进程的。...exec函数本质是一个加载函数,因为有了exec函数,在Linux中就可以将程序加载进去,因为进程程序替换的本质就是将不同的程序加载到内存里面,加载靠的就是exec*函数。...由参数,我们可以看到有pathname 和file,我们第一个使用的pathname即路径名,我们要从哪里执行程序,得通过该路径告诉它,file同理,就是文件名,那么对于execl,代表的就是列表,也就是在命令行中我们如何执行

    9510

    Linux之进程控制

    fork函数的实现在操作系统内部,当这个函数准备返回时,它的核心代码已经执行完了也就是子进程已经被创建了,并且已经在OS的运行队列中准备被调度了。...2.进程退出的方法 从主函数(main函数)return返回; 程序的任意位置调用exit(code); 系统调用_exit(code); 3....3.替换原理 为什么调用替换函数后,原程序的剩余部分不再执行?...当进程调用exec系列函数时,该进程的用户空间的代码和朱家具完全被新程序替换,从新程序的启动例程开始执行。 要注意,调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。...因此,原进程后续的代码会被新进程的代码和数据所覆盖,因此就不会执行剩余代码了。 这也是为什么只有当程序替换失败才会有返回值,因为如果替换成功就不会执行接下来的代码,返回值就无意义。

    19920

    【Linux】实现一个简易的shell命令行

    一.项目简介 在使用Linux的过程中,相信大家最熟悉的就是Linux的命令行使用方式了,我们可以给命令行输入任意有效指令, 然后命令行会根据我们输入的指令来完成相应的操作。...今天我们尝试在Linux使用C语言自己实现一个简单的shell命令行程序,它可以像真的命令行那样执行命令, 与程序员交互, 话不多说, 先来看看实现效果吧: myshell功能测试 二.分析项目实现...其中时间从左向右。shell由标识为sh的方块代表,它随着时间的流逝从左向右移动。shell从用户读入字符串"ls"。...shell建立一个新的进程,然后在那个进程中运行ls程序并等待那个进程结束。 然后shell读取新的一行输入,建立一个新的进程,在这个进程中运行程序 并等待这个进程结束。...学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步! 今天是2024.10.24, 祝广大程序员们: "编"出未来,"程"就梦想!

    13910

    极简shell制作

    ,后续程序就不会往下走,又因为进程之间具有独立性,所以需要创建一个子进程来完成进程替换这件事情。...带 ‘v’ 的接口也有三个,execvp 接口是最好的选择,为什么大家可以自己思考一下,很简单: execvp(argv[0], argv);//根据命令在环境变量里查找,在根据选项做出对应的动作   ...✈️内建命令处理 cd命令处理   我们来看这样一个现象:   命名我已经切换目录很多次了,但是为什么目录没有改变呢?...路径显示问题   这里还有一个很明显的错误行为,我的命令行解释器的路径从开始就没有变过,其实是因为我们没有更新PWD环境变量,我们可以手动给当前进程更新环境变量,使用一个数组存储当前目录,再使用 putenv...这个命令,这个命令需要显示上一个进程的退出码,而获取进程的退出码,这个时候我们就需要先在全局范围内设置退出码变量: int lastcode = 0;//退出码   退出码是在执行完进程之后返回的结果,

    14310
    领券