一起talk C栗子吧(第一百三十五回:C语言实例--exec系列函数一)

时间:2021-07-09 10:03:49

各位看官们,大家好,上一回中咱们说的是“创建线程时的内存细节”的例子,这一回咱们说的例子是: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系列函数的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。