zoukankan      html  css  js  c++  java
  • 进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏

    2014年5月30日  下午1:40:59

    1. Unix 进程执行环境:

      1.1 终止处理程序:

       ISO C 规定,一个程序可以登记多达32个函数,这些函数将由exit自动调用。我们称这些函数为终止处理程序(exit handler),并调用atexit函数来登记这些函数。该函数的原型如下: 

    1 #include <stdlib.h>
    2 
    3 int atexit(void (*function)(void));

     exit调用这些终止程序的顺序与他们登记时的顺序相反(先登记后调用)。同一个函数如果被登记多次也会被调用多次。

     下面我们来实际编写和登记一个终止处理程序:

           a). linux man_pages 上的程序: 


     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 
     5 void bye(void)
     6 {
     7     printf("That was all, folks ");
     8 }
     9 
    10 int main(void)
    11 {
    12     long a;
    13     int i;
    14 
    15     a = sysconf(_SC_ATEXIT_MAX);
    16     printf("ATEXIT_MAX = %ld ",a);
    17 
    18     i = atexit(bye);
    19     if(i != 0)
    20     {
    21         fprintf(stderr,"cannot set exit function ");
    22         exit(EXIT_FAILURE);
    23     }
    24 
    25     exit(EXIT_SUCCESS);
    26 }

     程序的输出结果是:

    ATEXIT_MAX = 2147483647
    That was all, folks

       b) APUE 上面的例题:


     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 void exit_func1(void);
     5 void exit_func2(void);
     6 void exit_func3(void);
     7 
     8 int main(void)
     9 {
    10     if(atexit(exit_func1) != 0)
    11         printf("failed to register exit_func1! ");
    12     if(atexit(exit_func2) != 0)
    13         printf("failed to register exit_func2! ");
    14     if(atexit(exit_func3) != 0)
    15         printf("failed to register exit_func3! ");
    16     exit(0);
    17 }
    18 
    19 void exit_func1(void)
    20 {
    21     printf("This is the exit_func1! ");
    22 }
    23 
    24 void exit_func2(void)
    25 {
    26     printf("This is the exit_func2! ");
    27 }
    28 
    29 void exit_func3(void)
    30 {
    31     printf("This is the exit_func3! ");
    32 }

     结果是:


    This is the exit_func3!
    This is the exit_func2!
    This is the exit_func1!

     显然推出处理函数的登记顺序和执行顺序是相反的!

       1.2 命令行参数:

       当执行一个程序时,调用exec的进程可以将命令行参数传递给新的进程! 

    1 #include <stdio.h>

    2 
    3 int main(int argc,char *argv[])
    4 {
    5     int i;
    6     for(i = 0; i < argc; i++) /* echo all command-line args */
    7         printf("argv[%d]: %s ",i,argv[i]);
    8     return 0;
    9 }

     上面这个函数原样输出命令行参数:

     ./a.out This is me:

    argv[0]: ./a.out
    argv[1]: This
    argv[2]: is 

     argv[3]: me 

    注意: C/C++的命令行参数是包含程序名称的! Java的命令行参数是不包含程序名称的!

    下面是一段显示Java命令行参数的源代码:


    1 public class javaargs
    2 {
    3     public static void main(String argv[])
    4     {
    5         for(int i = 0; i < argv.length; i++)
    6             System.out.printf("args[%d]: %s ",i,argv[i]);
    7     }

    8 } 

     在shell中输入命令 java javaargs This is me 之后:

    args[0]: This

    args[1]: is
    args[2]: me

     可以看到命令行参数是不包含程序名的!

       1.3 环境表和指向指针的指针:

       每个程序都会接收到一张环境表,和命令行参数列表一样,环境表也是一张字符指针数组。 

     

       但如何得到和修改环境表的某个表项?怎样得到整个环境表?

    #include <stdlib.h>
    char *getenv(const char *name);

    /*
    * The getevn() function searches the environment list to find the environment variable name, and 
    *returns a pointer to the corresponding value string

    */

    下面我们通过实际程序来验证如何得到特定环境变量:


     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 int main(void)
     5 {
     6     printf("The Env Var PATH is: ");
     7     printf("%s ",getenv("PATH"));
     8 
     9     printf("The Env Var HOME is: ");
    10     printf("%s ",getenv("HOME"));
    11 
    12     printf("The Env Var HOME is: ");
    13     printf("%s ",getenv("JAVA_HOME"));
    14 
    15     exit(0);
    16 }

     上面的程序在我的电脑上的运行结果是:

    The Env Var PATH is:
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin
    The Env Var HOME is:
    /home/jiangheng
    The Env Var HOME is: 

    /usr/lib/jvm/jdk 

    当然你的电脑上的结果根据你的系统配置而异。 

      那么如何设置新的环境变量呢? setenv 的原型如下:

    #include <stdlib.h>
    int setenv(const char *name,const char *value,int overwrite);
    int unsetenv(const char *name);
    /*
           The  setenv()  function  adds the variable name to the environment with
           the value value, if name does not already exist.  If name does exist in
           the  environment,  then  its  value is changed to value if overwrite is
           nonzero; if overwrite is zero, then the value of name is  not  changed.
           This  function makes copies of the strings pointed to by name and value
           (by contrast with putenv(3)).

           The unsetenv() function deletes the variable name from the environment.
           If  name does not exist in the environment, then the function succeeds,
           and the environment is unchanged.

    */ 

      下面我们通过程序来验证对环境变量的修改:


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

    int main(void)
    {
        char *path = getenv("PATH");     /* get the old path */
        puts("Old PATH: ");
        puts(path);
        path = strcat(path,":/home/jiangheng"); /* new PATH  */
        if(setenv("PATH",path,1) != 0)
            printf("Failed to set PATH! ");
        char *new_path = getenv("PATH"); /* get the new path */
        puts("");
        puts("New PATH: ");
        puts(new_path);
        exit(0);
    }

     首先打印原来的PATH,然后再打印修改后的PATH,结果如下:

    Old PATH: 

    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin

    New PATH: 
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin:/home/jiangheng

     显然我们修改了环境变量PATH!

       那么如何得到所有环境变量的值呢? 下面是得到所有环境变量的源代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 extern char **environ;
     5 
     6 int main(void)
     7 {
     8     int i = 0;
     9     while(environ[i] != NULL)
    10     {
    11         puts(environ[i]);
    12         i++;
    13     }
    14     exit(0);
    15 }

    程序的结果如下:

    XDG_VTNR=7

    SSH_AGENT_PID=1819
    XDG_SESSION_ID=c1
    CLUTTER_IM_MODULE=xim
    GPG_AGENT_INFO=/run/user/1000/keyring-NpJvov/gpg:0:1
    TERM=xterm
    SHELL=/bin/bash
    VTE_VERSION=3406
    XDG_SESSION_COOKIE=7cec1ada7aecdca275c3573653082170-1401399175.732373-1244795985
    CLUTTER_DISABLE_XINPUT=1
    WINDOWID=39845896
    GNOME_KEYRING_CONTROL=/run/user/1000/keyring-NpJvov
    USER=jiangheng
    LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
    SSH_AUTH_SOCK=/run/user/1000/keyring-NpJvov/ssh
    SESSION_MANAGER=local/jiangheng-Lenovo-U410:@/tmp/.ICE-unix/1720,unix/jiangheng-Lenovo-U410:/tmp/.ICE-unix/1720
    USERNAME=jiangheng
    DEFAULTS_PATH=/usr/share/gconf/default.default.path
    XDG_CONFIG_DIRS=/etc/xdg/xdg-default:/etc/xdg
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin:/usr/lib/jvm/jdk/bin:/usr/lib/jvm/jdk/jre/bin
    DESKTOP_SESSION=default
    GDM_XSERVER_LOCATION=local
    PWD=/home/jiangheng/AUEP/process/pro_evn
    XMODIFIERS=@im=fcitx
    JAVA_HOME=/usr/lib/jvm/jdk
    GNOME_KEYRING_PID=1644
    LANG=zh_CN.UTF-8
    MANDATORY_PATH=/usr/share/gconf/default.mandatory.path
    MDM_XSERVER_LOCATION=local
    GDMSESSION=default
    SHLVL=1
    XDG_SEAT=seat0
    HOME=/home/jiangheng
    GNOME_DESKTOP_SESSION_ID=this-is-deprecated
    LOGNAME=jiangheng
    QT4_IM_MODULE=xim
    XDG_DATA_DIRS=/usr/share/default:/usr/share/gnome:/usr/local/share/:/usr/share/:/usr/share/mdm/
    DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-HZ9f5B9T2y,guid=0eb168d6e01b1cf3e3ccd3465387a78b
    CLASSPATH=:/usr/lib/jvm/jdk/lib:/usr/lib/jvm/jdk/jre/lib:/usr/lib/jvm/jdk/lib:/usr/lib/jvm/jdk/jre/lib
    MDMSESSION=default
    TEXTDOMAIN=im-config
    WINDOWPATH=7
    XDG_RUNTIME_DIR=/run/user/1000
    DISPLAY=:0
    MDM_LANG=zh_CN.UTF-8
    XDG_CURRENT_DESKTOP=GNOME
    GTK_IM_MODULE=xim
    TEXTDOMAINDIR=/usr/share/locale/
    COLORTERM=gnome-terminal
    XAUTHORITY=/home/jiangheng/.Xauthority
    OLDPWD=/home/jiangheng
    _=./a.out

     显然我们通过extern char **environ;得到了所有的环境变量.

        

  • 相关阅读:
    关于virtualbox配置centos7的网络问题
    centos7在命令行下安装图形界面
    ajax后台返回指定的错误码
    h5前端animate等js特效问题汇总
    tp5中的input助手函数
    使网页滑动效果更加流畅
    关于vagrant环境下项目中图片缓存的问题
    h5图片预览功能
    微信jssdk遇到的一些问题汇总
    curl请求curl_exec返回false,curl_error返回空
  • 原文地址:https://www.cnblogs.com/jiangheng/p/3760874.html
Copyright © 2011-2022 走看看