Linux系统应用编程 --- 进程原语(二)

exec函数

1. exec函数作用

 用fork创建子进程后执行的是和父进程相同的程序,可以通过if判断pid的返回值让子进程执行不同的代码分支,这样设计程序不灵活。通过调用exec函数,用新程序将子进程的用户空间代码和数据替换,直接去执行新程序。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

2. execc族函数原型

其实有六种以exec开头的函数,统称exec函数:

#include <unistd.h>
 
int execl(const char *path, const char *arg, ...);
 
int execlp(const char *file, const char *arg, ...);
 
int execle(const char *path, const char *arg, ..., char *const envp[]);
 
int execv(const char *path, char *const argv[]);
 
int execvp(const char *file, char *const argv[]);
 
int execve(const char *path, char *const argv[], char *const envp[]);

exec函数特点:

1.exec函数如果调用成功则加载新的程序从启动代码开始执行,不再返回,如果调用出错则返回-1,所以exec函数只有出错的返回值而没有成功的返回值。

2.exec函数替换掉当前进程的用户空间,包括堆栈空间、代码段

 

3. 从code理解exec函数的作用

code 1 :

#include <stdio.h>
#include <unistd.h>
 
 
int main(void)
{
       printf("hello.\n");
       execl("/bin/ls", "ls", "-l", NULL);
       printf("world.\n");
       return 0;
}

执行结果:

 

分析:

可以看到没有执行      printf(“world.\n”);

这是因为/bin/ls加载到用户用户空间替换了原来代码段,所以execl下面的代码就不会执行了。所以程序是从ls的return 0退出程序的。

 

code 2 : 

include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void)
{
        pid_t pid;
        pid = fork();

        if(pid == 0)
        {
                /*in child*/
                execl("/usr/bin/firefox", "firefox", "www.baidu.com", NULL);
        }
        else if(pid > 0)
        {
                /*in parent*/
                while(1)
                {
                        printf("I am parent process\n");
                        sleep(1);
                }
        }
        else
        {
                perror("fork");
                exit(1);
        }

        return 0;
}

程序执行之后,父进程每隔1S循环打印你, 子进程调用firefox去打开网页。具体关系如下图。

重新打开一个终端,ps -aux可以看到

 子进程加载新的程序不再显示为a.out

4. exec函数辨析

execl与execlp

       execl("/bin/ls", "ls", "-l", NULL);

       execlp("ls", "ls", "-l", NULL);

execl要给全执行进程的路径,而execlp除了在当前路径下找,还可以去PATH环境变量底下找。p就是去环境变量底下找,不加p就是在当前路径下找,所以要给全路径

 

execv与execvp

这两个函数的功能跟excel与execlp的功能一样,只是将参数列表以数组指针的方式给出。

还是用上面执行ls举例

char *argvv[] = {“ls”, “-l”, NULL};

execv(“/bin/ls”, argvv);                execvp(“ls”, argvv);char *argvv[] = {“ls”, “-l”, NULL};

execv(“/bin/ls”, argvv);                execvp(“ls”, argvv);

execle execve中添加了一个替换环境变量的参数,在加载新的程序的时候,我们可以不用原来的环境变量。(这两个函数实际用的很少)
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页