各位看官们,大家好,上一回中咱们说的是“创建线程时的内存细节”的例子,这一回咱们说的例子是:exec系列函数。闲话休提,言归正转。让我们一起talk C栗子吧!
看官们,我们在前面介绍创建进程内存细节的章回中提到过exec系列函数,当时并没有做详细的介绍。今天我们将和大家一起看看exec系列函数。
exec系列函数可以把某个进程导入到调用exec系列函数的进程中,并且把当前进程替换成一个新的进程,在前面的章回中我们也介绍了,执行exec系列函数会触发写时复制,因此新进程拥有自己的代码区,数据区,堆区和栈区。
我们先从exec系列函数中选取一个函数来介绍,这样可以让大家有个直观的印象。下面是exec系列函数中的一个函数execlp,它的函数原型如下:
int execlp(const char *file, const char *arg, ...)
- 函数中的第一个参数是文件名,表示可执行文件名或者脚本文件名;
- 函数中的第二个参数是传递给可执行文件的参数,它会传递给可执行文件中main函数的argv[];
- 函数中的参数数量是可变的,不过最后一个参数总是空指针;
- 函数运行成功时没有返回值,运行错误时返回-1.
接下来, 我们通过实际的代码来说明如何使用该函数。下面是详细的代码,请大家参考:
#include<unistd.h>
#include<stdio.h>
int main()
{
pid_t pid;
pid_t pid_res;
int stat_value;
pid = fork();
if(pid > 0)
{
printf("PID: %d -> Father Process is running \n",getpid());
pid_res = wait(&stat_value);
if(pid_res > 0)
{
printf("Son process finished: PID = %d \n",pid_res);
}
}
else if(pid == 0)
{
printf("PID: %d -> Son Process is running \n",getpid());
execlp("echo","echo","hello",NULL); //运行execlp函数
}
else
{
printf("Create process failed \n");
return 1;
}
return 0;
}
上面的代码通过fork创建一个子进程,然后在子进程中执行execlp函数。我们重点看一下execlp函数的用法。
传递给函数的第一个参数是可执行文件名echo,第二个和第三个参数是”echo”和”hello”。这两个参数都会传递给可执行文件中(这里是echo)main函数的argv[]。最后一个参数是空指针,它也会传递给argv[]。这时候,我们来看看argv[]中的内容。
- argv[0]中的内容是”echo”;
- argv[1]中的内容是”hello”;
- argv[2]中的内容是”NULL”,它是命令结束标志。
可执行文件有了,可执行文件的参数也有了,真是万事俱备,只欠东风呀。看官莫急,东风来了,execlp函数就是东风,它会到系统的环境变量中查找可执行文件”echo”,并且把argv[]中的参数传递给它,然后运行该可执行文件。
下面是程序的运行结果,请大家参考:
PID: 4194 -> Father Process is running
PID: 4195 -> Son Process is running
hello //execlp函数把echo导入到当前进程中运行,并且输出运行结果
Son process finished: PID = 4195
我们也可以在终端中单独运行echo命令,下面是运行该命令的结果:
$ echo 'hello' //在终端中单独运行echo命令
hello //显示命令运行的结果
从上面的结果中,我们可以看到,它和刚才程序的运行结果是一致的。
各位看官,关于exec系列函数的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。