Linux编程-Linux进程(1)-进程环境

Linux进程环境
一、 进程启动
进程基本过程是内核调用exec函数,调用C程序的启动历程exit,exit从内核获取环境表及参数,传递给main。大致如下
内核exec-》exit(main(arg,argv));

二、 进程终止
1. 正常终止:
(1)main返回
(2)调用c 函数exit(C 退出函数会调用退出清理过程和关闭标准IO)
(3)调用内核退出函数_exit, _EXIT
(4)最后一个线程返回
(5)最后一个线程调用pthread)exit

2. 异常终止
(1)调用abort
(2)收到终止信号
(3)最后一个线程对取消请求做响应

三、注册退出清理函数(atexit)
#include <stdio.h>
#include <stdlib.h>
#include "process.h"
static void my_exit1()
{
printf("my_exit1\n");
}


static void my_exit2()
{
printf("my_exit2\n");
}


void CleanPro()
{
if (atexit(my_exit1) != 0)
{
printf("register clean funtion1 failed\n");
}


printf("Register my_exit1\n");


if (atexit(my_exit2) != 0)
{
printf("register clean funtion1 failed\n");
}


printf("Register my_exit2\n");


printf("Clean Pro Exit\n");
}
执行结果:
Register my_exit1
Register my_exit2
Clean Pro Exit
my_exit2
my_exit1

四、环境表
extern char **environ;
void testEnv()
{
if (NULL == environ)
{
printf("Environ is NULL\n");
return;
}


int i = 0;
while (NULL != environ[i])
{
printf("environ:");
printf("%s", environ[i]);
printf("\n");
i++;
}
//这里name=value,name和=之间不能有空格
char szbuf2[] = "tkf73381=a software engineer";
if ( 0 != putenv(szbuf2))//该处如果直接使用字符串常量会有告警,暂不能确定内存是由用户申请还是putenv申请
{
printf("put env failed\n");
return;
}
 
printf("get env tkf73381 = %s\n", getenv("tkf73381")); 
}
测试结果:
。。。
environ:LESSCLOSE=/usr/bin/lesspipe %s %s
environ:LC_TIME=en_US.UTF-8
environ:TEXTDOMAINDIR=/usr/share/locale/
environ:LC_NAME=en_US.UTF-8
environ:XAUTHORITY=/home/tkf73381/.Xauthority
environ:COLORTERM=gnome-terminal
environ:_=./IOTest
environ:OLDPWD=/home/tkf73381/Desktop
get env tkf73381 = a software engineer

其他环境表处理函数
#include <stdlib.h>
int setenv(const char *name, const char *value, int overwrite);//设置环境变量,如果不存在则创建,如果存在,由overwrite决定是否覆盖
int unsetenv(const char *name); //删除环境变量

五、程序空间布局
1. 布局说明
(1)正文段-text(程序指令)
通常为只读
(2)初始化数据段-data(全局变量或静态变量)
(3)非初始化数据-bss(该段内存不会存在程序文件中,及不会使得程序文件变大,会在进程中分配空间)
(4)栈-stack
一个栈帧是一个函数的执行时状态,主要包括返回地址、自动变量、临时变量、各寄存器上的值等信息
(5)堆-heap
是动态分配内存的地址空间,通常位于栈与非初始化数据段之间
(6)程序中还包括符号表段、调试信息段、共享库段等,这些不会加载到进程环境
2. 进程空间布局图示
高地址 命令行参数和环境变量
栈空间

堆空间

数据段   BSS段--未初始化数据()
DATA已初始化数据

低地址 正文段

3. 测试实例
size ./IOTest 
 text     data     bss     dec     hex filename
 5493 380      40    5913    1719 ./IOTest

六、共享库
cc -static hello.c 禁止使用共享库方式链接程序
cc hello.c     允许使用共享库方式链接程序

七、内存分配API
malloc分配的空间未初始化
calloc分配的空间被初始化为0
realloc如果重新分配的空间扩大了,原来空间中的内容会被复制到新空间中,新增长的部分未初始化
当老地址未NULL时,等价于malloc

free释放这三种方式分配的内存。
特征:
1. 三种方式分配的空间是适当对齐的
2. 分配的空间可能通常比实际的大,因为需要保存存储管理信息。
3. 某些系统提供更安全的内存管理版本。

八、程序的局部跳转与非局部跳转
goto来至c语言,用于实现程序的函数内部的局部跳转
setjmp 和longjmp 用于实现跨函数的跳转
1. longjmp的变量的影响
全局变量存储于数据区
不受longjmp影响
静态全局或局部变量存储于数据区(static)
不受longjmp影响
自动变量存储于栈区 (auto通常不写,所谓自动,是进入栈时自动分配,不会被初始化、栈结束时自动销毁)
可能会回滚到setjmp时的状态,不确定(优化编译和不优化编译可能不一样)
寄存器变量存储于寄存器 (register)
可能会回滚到setjmp时的状态,不确定(优化编译和不优化编译可能不一样)
易失变量存储于栈区 (volatile)
不受longjmp影响

编程实例:
int globval = 0;
static jmp_buf jmpbuffer;
void dojmp()
{
longjmp(jmpbuffer,1);
}




void testjmp()
{
int autoval = 1;
register int regival = 2;
volatile int volaval = 3;
static   int statval = 4;


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);
return;
}

autoval = 11;
regival = 21;
volaval = 31;
statval = 41;


printf("globval = %d, autoval = %d, regival = %d,"
"volaval = %d, statval = %d\n", 
globval, autoval, regival, volaval, 
statval);
dojmp();


}

测试结果:
globval = 0, autoval = 11, regival = 21,volaval = 31, statval = 41
after longjmp:
globval = 0, autoval = 1, regival = 2,volaval = 31, statval = 41

九、进程资源限制查询与修改
       #include <sys/time.h>
       #include <sys/resource.h>
       int getrlimit(int resource, struct rlimit *rlim);
       int setrlimit(int resource, const struct rlimit *rlim);
测试案例:
void testRlimit()
{
struct rlimit limit;
if (getrlimit(RLIMIT_AS, &limit) < 0)
{
printf("getrlimit error for %d\n", RLIMIT_AS);
return;
}


if (limit.rlim_cur == RLIM_INFINITY)
{
printf("infinite\n");
}
else
{
printf("soft limit:%ld\n", limit.rlim_cur);
printf("hard limit:%ld\n", limit.rlim_max);
}
}

测试结果:
infinite

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值