UNIX进程的环境(二)

2016-02-02

命令行参数

当执行一个程序时,调用exec的进程可将命令行参数传递给该新程序。
其中argv[0]是 程序名称

环境表

每个程序都接收一张环境表,与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null借宿的字符转的地址。全局变量environ则包含了该指针数组的地址。
extern char **environ
按照惯例环境由name=value这样的字符串组成。大多数预定义名全由大写字母组成。通常用getenv和putenv函数来存取特定的环境变量,而不是用environ变量,如果要查看整个环境则必须使用environ指针。

c程序的存储空间布局

由于历史原因,c程序一直由下列几部分组成

  • 正文段。这是由CPU执行的机器指令部分。通常正文段是可以共享的。多以即使是经常执行的程序在存储器中也只需有一个副本,另外正文段常常是只读的。防止程序由于意外事故而修改其自身的指令。
  • 初始化数据段。通常将此段成为数据段,它包含了程序中需要赋值的变量。例如c程序中任何函数之外的说明 int maxcount=99;使此变量以初值放在树池花数据段中。
  • 非初始化数据段。通常将此段成为bss,这一名称来源于早期汇编程序的一个操作符,在程序开始执行之前,内核程序将此段初始化为0,函数外的说明 long sum[1000];将次变量存放在非初始化数据段中。
  • 栈。 自动变量及每次函数调用时所保存的信息都存放在此段中。每次函数调用时其返回地址,以及调用者的环境信息都存放在栈中。然后新被调用的函数在栈上为其自动和临时变量分配储存空间。通过以这种方式使用栈,c函数可以递归调用。
  • 堆。同长在堆中进行动态内存分配。由于历史上形成的惯例,堆位于非初始化数据段顶和栈底之间

命令行参数和环境变量-->栈-->堆-->非初始化数据-->初始化数据-->正文
size命令报告正文段、数据段、bss段的长度

共享库

现在很多unix系统支持共享库,共享库是的可执行程序文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这一种库例程的一个副本。程序第一次执行或则第一次调用某个库函数时,用动态链接方法将程序与共享库函数相连接。这就减少了每个可执行文件的长度,但增加了一些运行时的开销。共享库的另一个优点是可以用库函数的新版本代替老版本而无需对使用该库的程序从新连接编辑。
不同的系统使用不同的方法使说明程序是否要使用共享库。比较典型的有cc和ls命令可选

存储器分配

ANSI C说明了三个用于存储空间动态分配的函数

  • malloc分配指定字符数的存储区。此存储区中的初始值不确定。
  • calloc为指定长度的对象,分配能容纳指定个数的存储空间,该空间中的每一位都初始化为0
  • realloc 更改以前分配去的长度。当增加长度时,可能需要将以前分配去的内容移到另一个足够大的区域,而新增区域内的初始值不确定。
void *malloc(size_t size);
void *calloc(sieze_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);
void free(void *ptr);

这单个分配函数所犯规的指针一定是适当对其的,使其可用于任何数据对象。例如,在一个特定的系统上,如果最苛刻的对其要求是double,则对其必须在8的倍数的地址单元处,那么这三个函数返回的指针都应这样对齐。
realloc在改变存储区大小的时候有可能会移动存储区的位置,因此不应当使用任何指针指向此存储区
realloc中若ptr为null则与malloc的功能相同。
这些分配例程通常调用sbrk系统调用实现。虽然sbrk可以扩从或者缩小一个进程的存储空间,但大多数malloc和free实现都不减小进程的存储空间,释放的空间可以供以后再分配,但他们被保存在malloc池而不返回给内核。
应当注意的是大多数实现所分配的存储空间比所要求的要稍微大一些,额外的空间用来记录管理信息分配块的长度,指向下一个分配快的指针等。这就意味着如果写过一个已分配区的尾端,则会改写后一块的管理信息。这种类型的错误是灾难性的。
其他的可能产生的致命性的错误是:释放了一个已经释放的块,调用free时所用的指针不是三个alloc函数返回值。
因为存储器分配出错很难跟踪,所以某些系统提供了这些函数的另外一种实现方法,每次调用者单个分配函数中的任意一个或者free时都进行附加的出错检查。

alloca函数

其调用序列与malloc相同,但是它是在当前函数的栈帧上分配存储空间,而不是在堆中。其优点是:当函数返回时,自动释放它所使用的栈帧,多以不必再为释放空间而费心。其缺点是:某些系统在函数一杯调用后不能增加栈帧的长度,于是也就不能支持alloca函数。

环境变量

如同前面所述,环境字符串的形式是:name=value
unix内核并不关心这种字符串的意义,他的解释完全取决于各个应用程序。
char *getenv(const char *name)
除了取环境变量,有时也需要设置环境变量,或者改变现有的变量的值,或者是增加新变量的(我们能影响的是当前进程及其后生成的子进程的环境,但不能影响父进程的环境)
int putenv(const char *str)
int setenv(const char *name, const char *value, int rewrite)
void unsetenv(const char *name)

setjmp和longjmp

在C中不允许使用跳跃函数goto 而执行这种跳转功能的是函数setjmp和longjmp这两个函数对于处理发生在很深的嵌套函数调用中出错情况非常有用。
int setjmp(jmp_buf env)
void longjmp(jmp_buf env, int val)
在希望返回到达的位置调用setjmp。setjmp的参数env是一个特殊类型jmp_buf这一数据类型是某种形式的数组,其中UC南方在调用longjmp时能用来恢复栈状态的所有信息。一般,env变量是个全局变量,因为需要从另一个函数中引用它。
当检查到一个错误时,则以两个参数滴啊用longjmp第一个就是在调用setjmp时所用的env第二个val是个非0值,它成为setjmp处返回的值。使用第二个参数的原因是对于一个setjmp可以有多个longjmp。

自动、寄存器和易失变量

当longjmp返回时,大多数实现并不回滚自动变量和寄存器变量。如果你有一个自动变量而又不想使其值回滚,则可以定义其为具有volatile属性。说明为全局和静态变量的值在执行longjmp时保持不变。因此如果要编写一个使用非局部跳转的可移植程序,则必须使用volatile属性。

自动变量的潜在问题

基本规则是说明自动变量的函数已经返回后,就不能再引用这些自动变量。

getrlinit和setrlimit函数

每个进程都有一组资源限制,其中某一些可以用getrlimit和setrlimit函数查询和更改
int getrlimit(int resource, struct rlinit *rlptr)
int setrlinit(int resource, const struct rlimit *rlptr)
对这两个函数的每一次调用都制定一个资源以及一个指向下列结构的指针

struct rlimit {
    rlimi_t rlim_cur;
    rlimi_t rlim_max;
}

进程的资源限制通常是在系统初始化时由0进程建立的,然后由后续进程继承。
更改资源限制时,需准守下列三条原则:

  • 任何一进程都可将一个软限制更改为小于等于其硬件限制
  • 任何一个进程都可降低其银监限制值,但它必须大于等于其软件限制值。这种降低对于普通用户而言是不可逆反的。
  • 只有超级用户可以提高硬件限制

资源限制影响到调用进程并由其子进程继承。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容

  • 一、温故而知新 1. 内存不够怎么办 内存简单分配策略的问题地址空间不隔离内存使用效率低程序运行的地址不确定 关于...
    SeanCST阅读 7,783评论 0 27
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,207评论 11 349
  • 史上最全的iOS面试题及答案 迷途的羔羊--专为路痴量身打造的品牌。史上最精准的定位。想迷路都难!闪电更新中......
    南虞阅读 1,497评论 0 8
  • 岁月是慢性流浪, 远方仍然是远方, 如今与别人无关, 谢谢自己够勇敢。 ——《谢谢自己够勇敢》 文丨旧故麻袋 ∨ ...
    旧故麻袋阅读 485评论 0 0
  • 提到猫,我没有特别的感觉,不是很喜欢也不是太讨厌。知道到传说中猫有九条生命,不知真假,而且猫是奸臣。我搞不明白...
    夏玫小墨阅读 477评论 9 2