Linux fork exec等

http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html

http://www.cnblogs.com/jimwind/archive/2012/12/26/2834147.html

http://www.cnblogs.com/hicjiajia/archive/2011/01/20/1940154.html

Linux下一个进程在内存里有三部分的数据,就是"代码段"、"堆栈段"和"数据段"。其实学过汇编语言的人一定知道,一般的CPU都有上述三种段寄存器,以方便操作系统的运行。这三个部分也是构成一个完整的执行序列的必要的部分。

  "代码段",顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用相同的代码段。"堆栈段"存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。这其中有许多细节问题,这里限于篇幅就不多介绍了。系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。 

1、fork 创建一个子进程,有两个返回值。返回0为子进程,返回大于0为父进程。

fork函数启动一个新的进程,前面我们说过,这个进程几乎是当前进程的一个拷贝:子进程和父进程使用相同的代码段;子进程复制父进程的堆栈段和数据段。这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。它们再要交互信息时,只有通过进程间通信来实现,这将是我们下面的内容。既然它们如此相象,系统如何来区分它们呢?这是由函数的返回值来决定的。对于父进程, fork函数返回了子程序的进程号,而对于子程序,fork函数则返回零。

2、exec 运行新的可执行文件,取代原调用进程的数据段、代码段和堆栈段。一般是运行fork后,在子进程中执行exec。

  我们来看看一个进程如何来启动另一个程序的执行。在Linux中要使用exec函数族。系统调用execve()对当前进程进行替换,替换者为一个指定的程序,其参数包括文件名(filename)、参数列表(argv)以及环境变量(envp)。exec函数族当然不止一个,但它们大致相同,在 Linux中,它们分别是:execl,execlp,execle,execv,execve和execvp,下面我只以execlp为例,其它函数究竟与execlp有何区别,请通过manexec命令来了解它们的具体情况。

  一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。(不过exec类函数中有的还允许继承环境变量之类的信息。)

一起使用的一个例子

1#include <errno.h>
 2#include <stdio.h>
 3#include <stdlib.h>
 4
 5char command[256];
 6void main()
 7{
 8   int rtn; /*子进程的返回数值*/
 9   while(1) {
10       /* 从终端读取要执行的命令 */
11       printf( ">" );
12       fgets( command, 256, stdin );
13       command[strlen(command)-1] = 0;
14       if ( fork() == 0 ) {/* 子进程执行此命令 */
15          execlp( command, NULL );
16          /* 如果exec函数返回,表明没有正常执行命令,打印错误信息*/
17          perror( command );
18          exit( errno );
19       }
20       else {/* 父进程, 等待子进程结束,并打印子进程的返回值 */
21          wait ( &rtn );
22          printf( " child process return %d\n", rtn );
23       }
24   }
25}

  

时间: 2024-10-01 07:03:43

Linux fork exec等的相关文章

Linux进程fork,exec,vfork详解

在Unix/Linux系统下进程创建时需要进行如下系统调用:fork/exec fork()把一个进程复制成二个进程:parent (old PID), child (new PID) exec()用新程序来重写当前进程:PID没有改变 接下来就重点学习这两个系统调用: 当我们fork() 创建一个继承的子进程将会发生如下事情:复制父进程的所有变量和内存,复制父进程的所有CPU寄存器(有一个寄存器例外)(这个寄存器是用来区分父进程和子进程的PID) fork()的返回值:调用fork()函数成功

Linux中exec命令相关

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两类:外部命令和内部命令.外部命令是通过系统调用或独立的程序实现的,如sed.awk等等.内部 命令是由特殊的文件格式(.def)所实现,如cd.history.exec等等. 在说明exe和source的区别之前,先说明一下fork的概念. fork是linux的系统调用,用来创建子进程(child

fork+exec 与system,popen区别

1.fork + exec fork用来创建一个子进程.一个程序一调用fork函数,系统就为一个新的进程准备了前述三个段,首先,系统让新的进程与旧的进程使用同一个代码段,因为它们的程序还是相同的,对于数据段和堆栈段,系统则复制一份给新的进程,这样,父进程的所有数据都可以留给子进程,但是,子进程一旦开始运行,虽然它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了.而如果两个进程要共享什么数据的话,就要使用另一套函数(shmget,shmat

在Linux使用exec执行命令时报的哪些错

问题1:find: paths must precede expression [[email protected] data]# find /oracle/backup/exp/data -name exp_table01_db01_*.dmp.gz -atime +2 exec rm -rf {}\;find: paths must precede expression: exp_table01_db01_20170928235039.dmp.gz 描述:在执行find命令时,在查找的内容必

Linux fork那些隐藏的开销

fork是一个拥有50年历史的陈年系统调用,它是一个传奇!时至今日,它依旧灿烂. 一个程序员可以永远不用read/write,也可以不懂mmap,但必须懂fork.这是一种格调! fork没有参数,它是如此简单,是UNIX哲学的布道者或者说卫道者们的首选,它被写进了几乎每一本操作系统教科书里,成了 创建新进程的绝佳范式 ,fork站在原地,似乎在闭着眼睛蔑视 Windows的CreateProcess ,它的参数是如此之多,如此之复杂,在UNIX的世界,简单就是一切! 然而UNIX却不是整个世界

shell调用另一个脚本的三种方式fork/exec/source

exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两类:外部命令和内部命令.外部命令是通过系统调用或独立的程序实现的,如sed.awk等等.内部命令是由特殊的文件格式(.def)所实现,如cd.history.exec等等. 在说明exe和source的区别之前,先说明一下fork的概念. fork是linux的系统调用,用来创建子进程(child

Linux中exec()执行文件系列函数的使用说明

函数原型: 描述:    exec()系列函数使用新的进程映像替换当前进程映像.    工作方式没有什么差别, 只是参数传递的方式不同罢了. 说明:    1. 这6个函数可分为两大类: execl()系列 和 execv()系列.    2. `l' 是指把所有传递给程序的参数依次列(list)出来.        `v' 是指把所有参数放到容器(数组, vector)中再一次性传入.         不论是list出来还是vector them all, 参数的最后一个都必须为空指针((ch

Linux fork炸弹解析 ——Linux Fork Bomb

Linux Fork Bomb :(){ :|: & };:是一个bash函数,以Fork Bomb闻名,是一个拒绝服务攻击 的Linux 系统.如果你好奇地去执行了这个命令,那么赶快重启系统吧~! 命令解析 :() { : | : & };: :在这里是一个函数名,我们定义之,并在后面执行它. :|:&,:函数的输出通过管道传给另一个冒号函数作为输入,并且在后台执行. { };标识着里面的内容是一个函数主体. 最后一个:为定义完成后的一次函数执行. 原理解析 首先需要说明的是:是

electron-vue在npm run build时报错 ? cannot execute cause=fork/exec C:\Users\801\AppData\Local\electron-builder\Cache\winCodeSign\winCodeSign-2.5.0\rcedit-ia32.exe: Access is denied.

问题描述 在electron-vue执行npm run build时报错,错误如下: ? cannot execute cause=fork/exec C:\Users\801\AppData\Local\electron-builder\Cache\winCodeSign\winCodeSign-2.5.0\rcedit-ia32.exe: Access is denied.command='C:\Users\801\AppData\Local\electron-builder\Cache\w