首页 > 其他 > 详细

进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏

时间:2014-05-31 17:37:46      阅读:408      评论:0      收藏:0      [点我收藏+]

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调用这些终止程序的顺序与他们登记时的顺序相反(先登记后调用)。同一个函数如果被登记多次也会被调用多次。

bubuko.com,布布扣

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

       a). linux man_pages 上的程序: 


bubuko.com,布布扣
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 
 5 void bye(void)
 6 {
 7     printf("That was all, folks\n");
 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\n",a);
17 
18     i = atexit(bye);
19     if(i != 0)
20     {
21         fprintf(stderr,"cannot set exit function\n");
22         exit(EXIT_FAILURE);
23     }
24 
25     exit(EXIT_SUCCESS);
26 }
bubuko.com,布布扣

 程序的输出结果是:

ATEXIT_MAX = 2147483647
That was all, folks

   b) APUE 上面的例题:


bubuko.com,布布扣
 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!\n");
12     if(atexit(exit_func2) != 0)
13         printf("failed to register exit_func2!\n");
14     if(atexit(exit_func3) != 0)
15         printf("failed to register exit_func3!\n");
16     exit(0);
17 }
18 
19 void exit_func1(void)
20 {
21     printf("This is the exit_func1!\n");
22 }
23 
24 void exit_func2(void)
25 {
26     printf("This is the exit_func2!\n");
27 }
28 
29 void exit_func3(void)
30 {
31     printf("This is the exit_func3!\n");
32 }
bubuko.com,布布扣

 结果是:


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

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

 

   1.2 命令行参数:

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

bubuko.com,布布扣
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\n",i,argv[i]);
8     return 0;
9 }

bubuko.com,布布扣

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

 ./a.out This is me:

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

 argv[3]: me 

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

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


bubuko.com,布布扣
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\n",i,argv[i]);
7     }
bubuko.com,布布扣

8 } 

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

args[0]: This

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

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

 

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

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

 bubuko.com,布布扣

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

bubuko.com,布布扣
#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
bubuko.com,布布扣

*/

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


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

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

bubuko.com,布布扣
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: 
bubuko.com,布布扣

/usr/lib/jvm/jdk 

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

 

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

#include <stdlib.h>
int setenv(const char *name,const char *value,int overwrite);
int unsetenv(const char *name);
bubuko.com,布布扣
/*
       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.
bubuko.com,布布扣

*/ 

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


bubuko.com,布布扣
#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!\n");
    char *new_path = getenv("PATH"); /* get the new path */
    puts("");
    puts("New PATH: ");
    puts(new_path);
    exit(0);
}
bubuko.com,布布扣

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

bubuko.com,布布扣
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

bubuko.com,布布扣

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

 

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

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

程序的结果如下:

bubuko.com,布布扣
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

bubuko.com,布布扣

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

    

 

 

 

 

 

 

 

 

进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏,布布扣,bubuko.com

进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏

原文:http://www.cnblogs.com/jiangheng/p/3760874.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!