APUE学习:进程环境

来源:互联网 发布:传智播客大数据第四期 编辑:程序博客网 时间:2024/05/21 06:41

进程终止

1)5种正常终止
a.从main返回
b.调用exit
c.调用_exit或_Exit
d.最后一个线程从启动例程返回
e.最有一个线程调用pthread_exit
2)3中异常终止
a.调用abort
b.接到一个信号终止
c.最有一个线程对取消请求作出响应
3)atexit函数,注册终止处理程序
退出处理函数,如果一个程序执行完之后,会执行我们用atexit注册的退出处理函数。退出处理函数的执行顺序与我们注册的顺序相反。

exit与_exit的区别

这里写图片描述

  • exit()会调用退出处理程序,之后会检查文件打开情况,清空I/O缓冲。最后调用sys_exit()。
  • 而_exit()函数不会调用退出处理程序,也不会清空I/O缓冲。意味着我们的在缓冲中的数据会丢失。_exit()函数只是直接调用sys_exit()。

环境表

存储器分配

#include <stdlib.h>void *malloc(size_t size);void *calloc(size_t nobj, size_t size);void *realloc(void *ptr, size_t newsize);void free(void *ptr);

1)malloc分配指定字节数的存储区,此存储区初始值不确定
2)calloc为指定数量指定长度的对象分配存储空间。该空间中的每一位都初始话为0。(注意0与浮点0以及空指针不一定相等)
3)realloc。更改以前分配区的长度。

环境变量

#include <stdlib.h>char *getenv(const char *name);int putenv(char *str);int setenv(const char *name, const char *value, int rewrite);int unsetenv(const char *name);

我们可以在环境变量中添加一个值,或者修改一个环境变量。但是需要注意的是,我们修改或者添加一个环境变量,影响的只能是我们这个进程以及我们的子进程。我们并不可以影响到我的父进程及祖先进程。

修改与删除一个环境变量是复杂的
1.修改
a.修改之后的变量小于以前变量。
b.修改之后的变量大于以前的变量,那么要获得一个内存空间,然后有一个指针指向这个新的环境变量。
2.添加
a.第一次添加,我们需要malloc获得一块地方存储我们以前的environment list+添加之后大小的空间。然后这个空间是在heap中的。
b.不是第一次添加,那么就是直接在heap中,remalloc

setjum函数与longjmp函数

#include <setjmp.h>int setjmp(jmp_buf env);void longjmp(jmp_buf env, int val);

说明:
1)直接使用setjmp之后,返回0。调用longjmp之后,会回到setjmp的地点,setjmp的返回值就是longjmp的val。
2)一个setjmp可以有多个longjmp。
3)在使用longjmp会到setjmp地点之后,该处的值不一定会回到之前使用setjmp的值。
4)自动变量的潜在问题。
5)setjmp可以在一个函数栈中设置一个env,通常这个env是一个全局类型的变量,在第一次设置的时候,setjmp返回0。并且会记录一些信息到env中。
调用longjmp之后,会返回到对应的env的setjmp中,此时setjmp的返回值是longjmp中的val。

注意点:

  • 这里说的问题是:
    如果我们的程序设计中有很多的函数调用,这样函数栈就会很大。此时如果我们其中一个函数出了不是很严重的错误,而且我们只是想打印这个错误,然后从main函数或者其他函数中再去执行,此时却因为函数调用栈太深而需要一步步的返回,造成性能上的浪费。
    在这种情况下,我们可以使用setjmp与longjmp函数,快速跳出函数栈的,直接返回到我们想要返回到的函数中。

  • longjmp依赖于setjmp设置的栈环境,比如f1->f2->f3->…->fN,如果在f1中我们设置了setjmp,得到了f1的栈环境。然后fN中调用了longjmp,想要到f1中处理对应情况。但是如果在调用longjmp之后,我们的f1函数自己因为一些原因退出了,释放了自己的栈空间,会造成longjmp引用一个非法的地址,造成错误。

getrlimit和setrlimit函数

#include <sys/resource.h>int getrlimit(int resource, struct rlimit *rlptr);int setrlimit(int resource, const struct rlimit *rlptr);

resourc的取值

问题:

1.只有在exec启动执行程序才会给程序开辟stack与heap空间,所以用size观察一个开执行文件时,看不到stack与heap空间大小。
2.在一个可执行文件中,会包含一些调试信息,所以一般可执行文件的大小与text+data的大小是不一样的。

0 0
原创粉丝点击