exce函数组
(1)exec函数族说明
fork()函数用于创建一个子进程,该子进程几乎复制了父进程的全部内容;exec函数族可以用来在一个进程中启动另一个可执行文件,该可执行文件将代替当前进程的执行映像(包括原调用进程的数据段、代码段和堆栈段)。该调用并没有生成新的进程,而是在原有进程的基础上,替换原有进程的正文,调用前后是同一个进程,除了进程号PID不变,其他全部被新的进程替换了。这里的可执行文件既可以是二进制文件,也可以是Linux下的任何可执行的脚本文件。
(2)exec函数族语法
所需头文件:
#include <unistd.h>
六种调用形式:
int execl(const char *path, const char *arg, ...)
int execv(const char *path, char *const argv[])
int execle(const char *path, const char *arg, ..., char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, ...)
int execvp(const char *file, char *const argv[])
函数返回值:
-1:出错
exec函数名对应位含义:
前4位:均为exec
第5位:L:参数传递为逐个列举的方式,其语法为const char *arg
V:参数传递为构造指针数组的方式,其语法为char *const argv[]
第6位:E:可传递新进程环境变量
P:执行文件查找可以只给出文件名,系统就会自动按照环境变量"$PATH"所指定的路径进行查找
(3)exec函数族应用举例
以下程序实现子进程执行可执行文件,父进程显示执行结果。
上代码
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
int index;
// char *list[]={"./t2","hello","world",NULL};
char **list;//不知道数组大小,动态分配大小
list=(char **)malloc((argc+1)*sizeof(char *));
//list[0]="./t2";
for(index=0;index<argc;index++)
{
list[index]=argv[index];
}
list[index]=NULL;
printf("excel pid:%d\n",getpid());
printf("excel begin!\n");
execvp(list[0],list);
// execl("./t2","hello","world",NULL);
// execvp(list[0],list);
//execlp("ls","ls","-l",NULL);
// execl("/bin/ls","ls","-l",NULL); //先传递路径
// execl("./t2","hello","world",NULL);//必须以NULL结尾
printf("excel end\n");
return 0;
}
fork()
fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的几乎完全相同,
将要执行的下一条语句都是if(fpid<0)……
为什么两个进程的fpid不同呢,这与fork函数的特性有关。
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,
fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。
引用一位网友的话来解释fpid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id,
因为子进程没有子进程,所以其fpid为0.
fork出错可能有两种原因:
1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
2)系统内存不足,这时errno的值被设置为ENOMEM。
创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。
每个进程都有一个独特(互不相同)的进程标识符(process ID),可以通过getpid()函数获得,还有一个记录父进程pid的变量,可以通过getppid()函数获得变量的值。
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
printf("ok1\n");
long int ret,retw;
ret=(long int)fork();
printf("oK2\n");
if(ret==0)
{
printf("child\n");
printf("iret fork :%d,pid :%d,ppid: %d\n",ret,getpid(),getppid());
sleep(5);
}
else
{
printf("father\n");
printf("iret fork :%d,pid :%d,ppid: %d\n",ret,getpid(),getppid());
printf("wait...\n");
retw=(long int)wait(NULL);
printf("the child retw:%d\n",retw);
printf("end...\n");
}
printf("%d pid exit\n",getpid());
return 0;
}