系统相关
首页 > 系统相关> > C7 : 进程环境

C7 : 进程环境

作者:互联网



1. 引言

1:程序执行时,main是如何被调用的

2:命令行参数如何传递给新程序

3:典型的存储空间布局样式

4:如何分配额外的储存空间

5:进程如何使用环境变量

6:进程的不同终止方式

7:longjmp和setjmp函数以及它们和栈的交互方式

8:进程的资源限制

2.main函数

main函数的原型是int main(int argc, char* argv[]);

内核执行c程序的步骤

内核调用一个启动例程

可执行程序文件将此启动例程指定为程序的起始地址

启动例程从内核获取命令行参数和环境变量参数

运行可执行文件

3.进程终止

5种正常终止方式

1、从main函数返回

2、调用exit

• int atexit (void (*__func) (void))

• exit返回时会调用atexit或者on_exit注册的回调函数

• 执行标准io库的清理关闭操作,对于所有打开的流调用fclose

3、调用_exit或_Exit

• _Exit返回时不调用atexit注册的回调函数

• 二者的区别

 

 

 

 

4、最后一个线程从启动例程中返回

5、从最后一个线程调用pthread_exit

3种异常终止

调用abort

接收到一个signal

最后一个线程对取消请求的响应

程序的启动和终止

 

 

 

 

4.命令行参数

argc

argv

ISO C和POSIX都要求argv[argc]为null

5.环境表

extern char** environ;

字符指针数组

 

 

 

 

6. 存储空间布局

正文段

CPU执行的指令部分

初始化数据段

程序中需要明确付初值的变量

可分为read write区域和read only区域

• "abc"在read only区域

• a在read write区域

未初始化数据段,bss: block started by symbol

long sum[1000];

存放程序中未初始化的全局变量(静态变量)的一块内存区域

自动变量以及函数调用需要保存的信息

堆中进行动态内存分配

典型的存储器排列

 

 

 

 

测试案例:https://www.geeksforgeeks.org/memory-layout-of-c-program/

高地址顶部:命令行参数和环境变量

7.共享库

8.存储空间分配

malloc

void *malloc (size_t __size)

分配指定长度的存储区,初始值不确定

calloc

void *calloc (size_t __nmemb, size_t __size)

分配指定长度的存储区,且每一位都初始化为0

realloc

void *realloc (void *__ptr, size_t __size)

增加或减少之前的分配区,可能需要将之前分配的内容移动到另一个足够大的区域。新增区域的初始值不确定

以上三个分配函数的指针一定是适当对齐的,可适用于任何数据对象

free

void free (void *__ptr)

9.环境变量

getenv

char *getenv (const char *__name)

putenv

int putenv (char *__string)

形式为name=value的字符串,覆盖已有名称的name

setenv

int setenv (const char *__name, const char *__value, int __replace)

设置name和value,如果name存在,且replace非0,则替换现有定义

unsetenv

int unsetenv (const char *__name)

删除当前的name

环境表位于存储空间的顶部,下面就是栈区

 

 

 

 

修改name对于的value

增加新的name

 

 

 

 

 

10. setjmp和longjmp

函数的调用栈

 

 

 

这俩函数用于实现函数栈帧之间的跳转

setjmp

• 返回0表示直接调用

• 返回非0,表示longjmp的跳转后的结果

 

 

 

longjmp

• 第一个参数是setjmp缓存的jmpbuf

• 第二个参数是跳转到setjmp后,setjmp的返回结果

longjmp之后的问题

1.自动变量、寄存器变量、易失变量volatile

• 不进行任何优化时,自动变量、全局变量、静态变量、寄存器变量、volatile变量都不会改变

• 优化后,全局变量、static变量、volatile变量不会改变,而其他变量可以改变

• 1:编译器不知道多线程访问的变量特征,不知情哪些变量是在别的线程中修改的

• 2:程序运行过程中,变量会被存储到寄存器的值,而寄存器内的值不会被中断(外部改变变量)影响

• 3:编译器优化,通常,只知晓当前线程的操作,对变量的访问判断仅进行一次读取,后续访问均从寄存器获得。尽管外部线程对该变量进行了改写,当前线程依旧使用当前线程的寄存器(旧的值)

• 4:加上volatile关键字后,编译器不会再对该变量进行任何优化。访问时,会从变量地址处重新获取数据

• 举例:signal是外部变量,多线程共享

 

 

 

• 编译器优化的,在初始赋值后,ax不会再有任何改变

 

 

 

• 这是加上volatile关键字后,循环内部每次访问到ax,则重新读取

 

 

 

11.进程的资源限制

getrlimit

int getrlimit (__rlimit_resource_t __resource,      struct rlimit *__rlimits)

setrlimit

int setrlimit (__rlimit_resource_t __resource,      const struct rlimit *__rlimits)

资源限制,软限制和硬限制(软限制的最大值)

 

标签:__,调用,变量,int,void,环境,进程,C7,name
来源: https://www.cnblogs.com/hgwang/p/14761084.html