进程环境

进程终止

有8种方式使进程终止,当中5中为正常终止,它们是

1)      从main返回

2)      调用exit

3)      调用_exit或_Exit

4)      最后一个线程从其启动例程返回

5)      最后一个线程调用pthread_exit

异常终止有3中方式

6)      调用abort

7)      接到一个信号并终止

8)      最后一个线程对取消请求做出对应

exit函数

#include <stdlib.h>

void exit(int status);

void _Exit(int status);

#include <unistd.h>

void _exit(int status);

三个函数都带有一个整形參数,成为终止状态。

exit函数总是先运行一个标准I/O库的清理关闭操作:为所以打开流调用fclose函数,这会造成所以缓冲区的输出数据都被冲洗。

exit(0)等价于return(0)。

atexit函数

依照ISO C的规定,一个进程能够登记多达32个函数,这些函数将由exit自己主动调用。我们称这些函数为终止处理程序,并调用atexit函数来登记这些函数。

#include <stdlib.h>
int atexit(void (*function)(void));
当中,atexit的參数是一个函数地址,当调用此函数时无需向它传送不论什么參数,也不期望它返回一个值。exit调用这些函数的顺序与他们被atexit登记的顺序相反。同一函数如登记多次,则也会被调用多次。例如以下是使用atexit的程序。
#include "stdlib.h"
#include "stdio.h"
static void my_exit1(void);
static void my_exit2(void); int main(void)
{
if (atexit(my_exit2) != 0)
perror("can't register my_exit2"); if (atexit(my_exit1) != 0)
perror("can't register my_exit1");
if (atexit(my_exit1) != 0)
perror("can't register my_exit1"); printf("main is done\n");
return(0);
}
static void my_exit1(void)
{
printf("first exit handler\n");
} static void my_exit2(void)
{
printf("second exit handler\n");
}

输出结果例如以下:

main is done

first exit handler

first exit handler

second exit handler

命令行參数

内核是程序运行的唯一方法是调用exec函数。当运行一个程序时,exec的进程可将命令行參数传递给该新程序。

C程序的存储空间布局

正文段:这是由CPU运行的机器指令部分。通常正文段是能够共享的。

初始化数据段:通常将此段成为数据段。包括程序中明白赋初值的全局变量或静态变量。

非初始化数据段:通常称此段为BBS段(block startedby ymbol),未赋初值的全局变量或静态变量。在程序运行之前,内核将此段的数据初始化为0或空指针。

栈:自己主动变量以及每次函数调用时所需保存的信息都存放在此段中。

堆:通常在堆中进行动态存储分配。

C程序典型的存储安排例如以下所看到的:

用size命令报告正文段、数据段和bbs段的长度。

环境表和环境变量

环境表

每个程度都会接收到一张环境表。环境表是一个字符指针数组,当中每个指针包括一个以null结束的C字符串的地址。全局变量environ则包括了该指针数组的地址:

extern char**environ

比如,假设该环境包括5个字符串,则其示意图例如以下

当中每一个字符串结尾都显示的有一个null字符。我们称environ为环境指针,指针数组为环境表,当中各个指针所指字符串为环境字符串。

环境变量

环境字符串的形式通常例如以下:

name = value

ISO C定义了一个函数getenv用于取环境变量值:

#include <stdlib.h>

char *getenv(const char *name);

此函数返回一个指针,指向name = value字符串中的value。未找到返回NULL。

#include <stdlib.h>

int putenv(char *string);

int setenv(const char *name, const char*value, int overwrite);

int unsetenv(const char *name);

putenv取形式为name = value的字符串,将其放到环境表中。假设name已近存在,则先删除原定义。

setenv将name设置为value。

unsetenv删除name的定义。

环境表和环境字符串通常存储在空间的顶部(栈之上)

setjmp和longjmp

C语言中goto是不能跨越函数的,运行这类跳转功能的函数是setjmp和longjmp。

#include <setjmp.h>

int setjmp(jmp_buf env);

void longjmp(jmp_buf env, int val);

通过程序来看看自己主动变量、全局变量、寄存器变量、静态变量和易失变量的不同情况:

#include <stdio.h>
#include <setjmp.h> static void f1(int, int, int, int);
static void f2(void); static jmp_buf jmpbuffer;
static int globval; int main(void)
{
int autoval;
register int regival;
volatile int volaval;
static int statval; globval = 1; autoval = 2; regival = 3; volaval = 4; statval = 5; if (setjmp(jmpbuffer) != 0) {
printf("after longjmp:\n");
printf("globval = %d, autoval = %d, regival = %d,"
" volaval = %d, statval = %d\n",
globval, autoval, regival, volaval, statval);
exit(0);
} /*
* Change variables after setjmp, but before longjmp.
*/
globval = 95; autoval = 96; regival = 97; volaval = 98;
statval = 99; f1(autoval, regival, volaval, statval); /* never returns */
exit(0);
} static void
f1(int i, int j, int k, int l)
{
printf("in f1():\n");
printf("globval = %d, autoval = %d, regival = %d,"
" volaval = %d, statval = %d\n", globval, i, j, k, l);
f2();
} static void
f2(void)
{
longjmp(jmpbuffer, 1);
}

其运行结果例如以下:

in f1():

globval = 95, autoval = 96, regival = 97,volaval = 98, statval = 99

after longjmp:

globval = 95, autoval = 2, regival = 3,volaval = 98, statval = 99

可见全局变量、静态变量和易失变量不受影响,自己主动变量和寄存器变量是否变化是不确定的(虽然这里显示恢复setjmp的值)。

getrlimit和setrlimit函数

#include <sys/time.h>

#include <sys/resource.h>

int getrlimit(int resource, struct rlimit*rlim);

int setrlimit(int resource, const structrlimit *rlim);

每一个进程都有一组资源限制,当中一些能够用getrlimit和setrlimit函数查询和更改。进程的资源限制一般是在系统初始化时由进程0建立的,然后由每一个后序进程继承。

Linux/UNIX之进程环境的更多相关文章

  1. Linux/Unix分配进程ID的方法以及源代码实现

    在Linux/Unix系统中.每一个进程都有一个非负整型表示的唯一进程ID.尽管是唯一的.可是进程的ID能够重用.当一个进程终止后,其进程ID就能够再次使用了. 大多数Linux/Unix系统採用延迟 ...

  2. 编写Linux/Unix守护进程

    原文: http://www.cnblogs.com/haimingwey/archive/2012/04/25/2470190.html 守护进程在Linux/Unix系统中有着广泛的应用.有时,开 ...

  3. Linux下的进程环境

    僵尸进程.孤儿进程.守护进程.进程组.会话.前台进程组.后台进程组 1,僵尸进程 子进程结束,父进程没有明确的答复操作系统内核:已收到子进程结束的消息.此时操作系统内核会一直保存该子进程的部分PCB信 ...

  4. (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. Linux Unix 环境变量设置实例

    背景 从第一次写Hello World我们便开始接触环境变量.这最基础的系统设置是必须要掌握的,尤其在是Linux/Unix系统中.比如,哪天某个Java进程出现问题,我们想分析一下其线程堆栈,却发现 ...

  6. Supervisor安装与配置(Linux/Unix进程管理工具)

    原文链接:http://blog.csdn.net/xyang81/article/details/51555473 Supervisor(http://supervisord.org/)是用Pyth ...

  7. Supervisor(Linux/Unix进程管理工具)安装与配置

    参考链接:https://blog.csdn.net/xyang81/article/details/51555473 Supervisor(http://supervisord.org/)是用Pyt ...

  8. Linux进程环境

    Linux下C程序都是main开始的,main函数的原型是: int main(int argc, char **argv) 其中argc是命令行参数的数目,argc是指向参数的各个指针所构成的数组. ...

  9. Unix环境高级编程(五)进程环境

    本章主要介绍了Unix进程环境,包含main函数是如何被调用的,命令行参数如何传递,存储方式布局,分配存储空间,环境变量,进程终止方法,全局跳转longjmp和setjmp函数及进程的资源限制. ma ...

随机推荐

  1. swift class extension 与继承

    1.扩展中无法继承重写已有函数,不能添加函数. Extensions can add new functionality to a type, but they cannot override exi ...

  2. CAD使用GetAllAppName读所有名称(com接口)

    主要用到函数说明: MxDrawEntity::GetAllAppName 得到所有扩展数据名称,详细说明如下: 参数 说明 [out, retval] IMxDrawResbuf** ppRet 返 ...

  3. 并发2-Synchronized

    一.Synchronized的概念 是利用锁的机制来实现同步的. 锁机制有如下两种特性: 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个 ...

  4. 字符串匹配算法之BM算法

    BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...

  5. CF147B Smile House

    题目大意:给定一个有向图,其中边有边权.求点数最少的正环的点数. 题解:建立矩阵,处理其二进制上每一位的状态.时间O(n^3*log(n)). 代码: #include<cstdio> # ...

  6. 如何在 CentOS 7 上生成 SSL 证书为 Nginx 加密

    本文首发:开发指南:如何在 CentOS 7 上安装 Nginx Let’s Encrypt 是由 Internet Security Research Group (ISRG) 开发的一个自由.自动 ...

  7. 理解javascript中的Array类型

    引子: 从事前端开发有段时间了,个人观点:想在前端开发这条路上走的更远,不仅要学好HTML&HTML5.CSS&CSS3,最重要的就是要学好javascript了.所以打好javasc ...

  8. jsp学习之如何在web层创建Servlet

    jsp动态网页的文件目录结构如下: 1.src下存放java代码 2.包web_xx为web层 3.webcontent里面是jsp文件 jsp页面中的请求交付给servlet处理,在实际中 jsp的 ...

  9. NYOJ-769乘数密码,逆元解法;

    乘数密码 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 ->    Link    <- 简单代替密码的第二种,比移位密码稍微复杂点,不过鉴于NYOJ,是完全可以 ...

  10. hihoCoder#1120 小Hi小Ho的惊天大作战:扫雷·三

    原题地址 看上去非常复杂, 实际上是这一系列最简单的一步,本质上是个搜索过程,相比于前一道题,可以不用策略三,而且题目的数据规模超级小,所以暴力搜索就能过. 把尚未确定的点放在一个unsettled列 ...