第七章 进程环境

来源:互联网 发布:凯旋软件 编辑:程序博客网 时间:2024/04/30 18:43

7.3进程终止

有八种方式使进程终止,5种为正常终止
1、从main返回
2、调用exit
3、调用_exit 或 _Exit
4、最后一个线程从启动例程返回
5、最后一个线程调用pthread_exit
异常终止的3种方式
6、调用abort函数
7、接到一个信号
8、最后一个线程对取消请求作出响应。

不管进程如何终止,最后都会执行内核中的同一段代码。这段代码为相应的进程关闭所有打开的文件描述符,释放它所使用的存储器。

atexit函数
一个进程可以登记多至32个函数,这些函数将由exit自动调用,这些函数称为终止处理程序,并调用atexit函数来登记这些函数
且exit调用这些函数的顺序与他们的登记的时候顺序相反
//成功返回0,出错返回非0
int atexit(void (*func)(void))//接受一个函数地址作为参数,作为参数的函数,无参数无返回值

eg:static void my_exit2(void){    printf("second exit handler\n");} void main(void){    if (atexit(my_exit2) != 0)        printf("can't register my_exit2\n");    printf("main is done\n");    exit(0);} 

注意:内核是程序执行的唯一方法是调用一个exec函数,进程自愿终止的唯一方法是显示或隐式地调用_exit和_Exit,进程也可以非自愿的接受一个信号使其终止。
思考: if (atexit(main) != 0) printf(“can’t register my_exit2\n”);会怎么样?
程序会陷入死循环

7.5环境表

每一个程序都接受到一张环境表。环境表是一个字符指针数组,其中每一个指针包含一个以null结束的C字符串的地址。
环境表

7.6 C程序的存储空间布局

C程序一直由下列几部分组成:
正文段:这是由CPU执行的机器指令部分。通常,正文段是可以共享的,正文段常常是只读的,防止程序由意外而修改指令。
初始化数据段: 也成为数据段;包含了程序中需要明确地赋初值的变量
未初始化的数据段:内核将此段中的数据初始化为0或者空指针。
:自动变量以及每次函数调用时所需保存的信息都存放在此段中,函数的返回地址以及调用者的环境信息。
:通常在堆中进行动态存储分配。
提示:未初始化的数据段内容并不存放在磁盘程序文件中,需要存放在磁盘程序文件中的只有正文段和初始化数据段。

7.7共享库

共享库使得可执行文件中不在需要包含公用库函数,而只需在所有进程都可引用的存储区中保存这种库例程的一个副本,程序第一次执行或者第一次调用时某个库函数时,用动态连接的方法将程序与共享库函数相连接,这减少了每个可执行文件的长度,但增加了一些时间开销。

7.8存储空间的分配

存储空间动态分配的3函数
//成功返回非空指针,出错返回NULL
void *malloc(sizt_t size); //分配指定字节数的存储区,此存储区中初始值不确定

void *calloc(size_t nobj, size_t size);//指定数量指定长度的对象分配存储空间,该空间每一位都初始化为0.

void * realloc(void * ptr, size_t newsize);//增加或者减少以前分配区的长度。如果存储区后有足够的空间可供扩充,则在原存储位置上向高地址方向扩充,无需移动任何原先内容,返回与传给它相同的指针值。如果没有足够的空间,则分配另一个足够大的存储区,将原来的元素内容复制到新分配的存储区,释放原存储区,返回新分配的指针。
使用这三个函数时,使用free函数避免造成内存泄露。

7.9环境变量

获取环境变量值得函数
//返回值:指向与name关联的value的指针;未找到,返回NULL;
char * getenv (const char *name);//返回一个指向 name = value字符串中的value。

设置或修改现有环境变量的值
只是影响当前进程及其后生成和调用的任何子进程的环境,但不能影响父进程的环境
int putenv(char * str);//取形式为name = value 的字符串,将其放入环境表中。如果name已经存在,删除原来的定义。

int setenv(const char *name, const char *value, int rewrite);//将name设置为value。如果环境变量中name已经存在,若rewrite非0,则首先删除其现有的定义;若rewrite为0,则不删除其现有定义

int unsetnv(const char *name); //删除name的定义

7.10函数setjmp和longjmp

用途:用于处理发生在很深层嵌套函数调用中的出错的情况;

int setjmp(jmp_buf env);//若直接调用返回0,若从longjmp返回,则为非0;

jmp_buf 这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。

void longjmp(jmp_buf env , int val);//参数env和setjmp函数的参数一样,val为setjmp的返回值。

当longjmp返回到main函数时,大多数实现并不回滚这些自动变量和寄存器变量的值;如果有一个自动变量,又不想回滚其值,可以定义其具有volatile属性,声明全局变量或者静态变量的值在执行longjmp时保持不变。

回滚(Rollback)指的是程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为

0 0
原创粉丝点击