系统编程-进程环境

``### 进程环境
启动例程:当进程调用main函数前,先调用一个特殊的启动例程,该程序是程序的起始地址
进程的终止;正常(进程main返回,进程exit,最后线程启动例程返回,最后线程exit) 异常(abort,终止信号,响应启动请求)
进程的exit: 有三个_exit和_Exit立即进入内核,exit先执行一些清理(关闭流,终止处理),然后进入内核

#include <stdlib.h>
void exit(int status)
void _Exit(int status)
#include <unistd.h>
void _exit(int status)

终止前处理,atexit,调用该接口注册退出时执行函数,当使用exit时,自动调用atexit,从而执行注册函数
exit调用这些注册函数时,执行的顺序与登记的顺序相反(链表),相同函数可以被多次登记,视作不同函数
最多可以注册32个

#include <stdlib.h>
int atexit(void (*func)(void));

image

命令行参数: for(i = 0; argv[i] != NULL; i++)
环境表:

方法一:
extern char **environ;
for(i = 0; environ[i] != NULL; i++)
//每个环境变量都是 name=value

方法二:
int mian(int argc, char *argv[], char *envp[]);

//通过name 获取value
#include<stdlib.h>
char *getenv(char *name);
//设置环境变量,str是 name=value的形式
int putenv(char *str); 
int setenv(char *name, char *vlaue, int rewrite)

int unsetenv(char *name)

c内存分布:
从下到上, 代码段,初始化数据段, 未初始化数据段, 堆,空闲空间 ,栈,命令行参数和环境变量,内核映射地址
使用size命令可以 查看ELF文件的段长度

共享库:
优点一:多个程序可以共用一份库副本,减少了可执行文件的长度。代价是增加了运行时间开销,开销发生在第一次调用共享库时。
优点二:共享库中老的函数可以被新的函数替代,但是无需重新编译(前提是参数的 数目和类型没有变化)

动态内存分配:

#include <stdlib.h>
malloc
calloc
realloc
free

malloc 通常会分配比实际空间大的一块区域,额外的区域用于记录管理信息。
malloc 是通过brk 和sbrk实现的,当free时,并不会缩小进程的堆, 而是用一个链表维护空闲空间
空闲链表的指针通常存放在分配的存储空间内,而不是额外空间。
由于额外空间记录着管理信息,对一块已经分配空间的尾部溢出写操作会覆盖管理信息,造成灾难性的错误(不但难以发现,而且恢复起来也很困难)
其他的致命错误:对未分配的空间free。调用malloc 却不释放(leakage)。

跨函数跳转:
setjmp和longjmp

进程资源限制:
getrlimit 和 setrlimit

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

struct rlimit{
	rlim_t rlim_cur; // 软限制
	rlim_t rlim_max; // 硬限制
}

//无限制 宏
RLIM_INFINITY

两个限制都可修改,但是有要求:
软限制必须小于等于硬限制;
只有超级用户能提高硬限制;
image

posted @ 2022-07-11 09:45  木瓜粉  阅读(25)  评论(0编辑  收藏  举报