• 执行新程序以及环境变量


    关键字:子进程,exec,环境变量

    使用fork或vfork创建子进程后,子进程通常会调用exec函数来执行另外一个程序。系统调用exec用于执行一个可执行程序以

    替代当前进程的执行映像。

    注意:exec调用并没有创建新的进程。一个进程一旦调用exec函数,它本身就“死亡”了,系统把代码段替换成新的程序的代码,

    废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一保留的就是进程ID。也就是说,对系统而言,还是

    同一个进程,不过执行的已经是另外一个程序了。

    exec函数:

    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 execvpe(const char *file, char *const argv[],char *const envp[]);

    --------------------------------------------------------------------------------

    环境变量:用户的主目录,终端类型,当前目录等,它们定义了用户的工作环境,所以称为环境变量。

    可以使用指令env查看系统环境变量。

    用户也可以修改这个变量的值,以制定自己的工作环境。

    代码中通过系统预定义的全局变量environ显示各个环境变量的值。

    事实上main函数的完整形式应该是:

    int main(int argc, char* argv[], char** envp);

    参数envp就是系统环境变量。

    测试代码:

    #include <stdio.h>
    #include <unistd.h>
    
    extern char** environ;
    
    int main(int argc, char** argv, char** envp)
    {
        char** p = environ;
        char** q = envp;
        while(*p != NULL)
        {
            printf("%s
    ", *p++);
            printf("%s
    ", *q++);
            printf("----------
    ");
        }
    
        
        return 0;
    }

    -----------------------------------------------------------------------------------------------

    exec函数与环境变量的关系:

    无论是哪个exec函数,都是可以将可执行程序的路径、命令行参数和环境变量3个参数传递给可执行程序的main函数。

    程序一:p.c

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(int argc, char* argv[], char **envp)
    {
    	int i = 0;
    
    	printf("after execve, my pid is:%d
    ", getpid());
    
    	for(i=0;i<argc;i++)
    	{
    		printf("argv[%d]=%s
    ", i, argv[i]);
    	}
    
    
    
    	return 0;
    }
    

      

    程序二:ex.c

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    
    int main(int argc, char* argv[], char* envp[])
    {
        pid_t pid = 0;
        int stat;
    
        printf("test execve
    ");
        
        pid = fork();
    
        if (pid < 0)
        {
            exit(0);
        }
        else if (pid == 0)
        {
            printf("the child's pid is:%d
    ", getpid());
            
            execve("p", argv, envp);
            
            printf("go on run
    ");
        }
        
        printf("parent is running
    ");
        wait(&stat);
        printf("quit
    ");
    
        
        return 0;
    }

    将第一个程序编译:

    gcc -o p p.c

    编译第二个程序:

    gcc -o ex ex.c 

    执行ex程序:

    test execve
    parent is running
    the child's pid is:26152
    after execve, my pid is:26152
    argv[0]=./ex
    argv[1]=ll
    quit

    从执行结果来看,execve调用的程序,保持了原来的进程ID,父进程ID。

    同时,我们还可以看到当调用新的可执行程序后,原有的子进程的映像被替代,不在被执行。

    子进程不会去执行printf("go on run ");因为子进程已经被新的执行映像替代。

    执行新程序后的进程保持了原来进程的许多特征,如:

    1、文件锁

    2、控制终端

    3、当前工作目录

    4、根目录

    5、创建文件时使用的屏蔽字

    6、进程信号屏蔽字

    7、未决警告

    8、和进程相关的使用处理器的时间

    9、实际用户ID

    10、实际组ID

  • 相关阅读:
    3(翻译)如何在cocos2d里面使用动画和spritesheet
    Objectivec2.0 每种数据类型定义属性的方法
    cocos2d 入门必备4个基本概念
    如何在Mac上搭建自己的服务器——Nginx
    JN_0001:在微信朋友圈分享时长大于10s的视频
    JN_0002:Win10禁止U盘拷贝文件的方法
    abstract class 和 interface区别
    ref和out
    .Net配置错误页
    Unity3d 物体沿着正七边形轨迹移动
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/6420524.html
Copyright © 2020-2023  润新知