Unix 高级编程-7 进程环境

 首先了解一个进程,首先需要了解进程环境。当程序执行的时候,main函数时如何被调用的,命令行参数是如何传递给新的程序的。进程的储存分布空间是什么样子的,如何分配另外的储存空间。

1.main 函数

   在c语言中,main函数是执行的入口函数。

int main(int argc, char *argv[]);

argc 是命令行参数,argv 是指向参数的各个指针所构成的数组。

当内核执行程序的时候,在调用main之前首先会调用一个特殊的启动例程, 可执行文件将此历程设置为程序的起始地址,这是由c编译器调用连接器设置的。

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

命令行参数:

当执行一个程序时,调用exec的进程可以将命令行参数传递给新的程序。

创建一个main.c 文件

#include "stdio.h"
int main(int argc, char *argv[])
{
    int i=0;
    for(int i=0;i<argc;i++)
   {
       printf("argv[%d]:%s\n",i,argv[i]);
   } 

}

gcc main.c

2.main函数的终止

main函数也是一个进程,描述main函数的终止,也可以介绍进程的终止。

一共有8种方式进行终止。

(1) 从main中正常返回。

 (2) 调用exit()。

(3)调用_exit 或_Exit()。

 (4) 最后一个线程从其启动例程中返回。(启动例程是什么)

 (5)最后一个线程调用pthread_exit()

异常终止

  (7) 调用abort。

  (8) 接受到一个信号。

  (9) 最后一个线程对取消线程作出响应。

上一节提到的启动例程是这样编写的,使得main函数返回后立即调用exit函数。启动例程的代码。

exit(main(argc,argv));

退出函数中,_exit()、_Exit() 直接进入系统内核。exit函数执行一些清理函数之后才会返回内核。

在函数中,调用 

exit(0);

 等同于 

return 0;
#include <stdlib.h>
void exit(int status);
void _Exit(int status);

#include <unistd.h>

void _exit(int status);

进程的终止函数,主要返回的是进程的终止状态,是一个整型。

如果main函数没有显示的使用return 函数或者exit函数,则进程的终止状态时未定义的。

进程终止的时候,可以exit()函数调用进程 终止处理程序。并且可以调用atexit函数来登记这些函数。

#include <stdlib.h>

int atexit(void (*func) (void));

  atexit函数传递的是函数的地址,无须向它传递任何参数。执顺序与登记顺序相反。终止程序每登记一次被调用一次。

内核使程序执行的唯一方法是调用exec函数,进程自愿终止的方法是显示或者隐式的调用exit函数。

环境表:

每一个程序都有一个环境表。环境表每一个都是字符串指针。每一个指针都包含一个以null为结束的c字符串的地址。

ISO C 定义了一个标准的I/O 函数。

#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);

此函数返回一个指针指向 name=value的字符串。(对于环境变量的了解,可以看一下鸟哥的linux私房菜)。 

除了获取环境变量,还要设置环境变量,需要增加环境变量等。

putenv 取形式为name=value 的字符串,将其放在黄健列表中。

setenv 是将name的值设置为value。

unsetenv 删除name的定义,即使不存在这个定义也不会出错。

这些函数在修改环境列表时是如何操作的。

删除一个字符串很简单,首先--只在环境列表中找到该指针,然后将所有后续指针向前移动一个位置。如何增加一个字符串指针。  环境表和环境指针都指向进程地址空间的顶部,所以它不能往高地址扩展。也不能移动低地址的栈帧。

如果修改一个现有的name:

1. 如果新value 的长度少于或等于现有的value值,将新字符串复制到原字符串的空间。

2.新的value大于原来的长度,需要从新分配内存空间。malloc申请内存,环境表中的指针指向新的分配内存。

3 c程序的储存空间布局:

基本常用的空间布局:

正文段:也是代码段,可以共享。

初始化数据段:

未初始化数据段:

栈:自动变量,局部变量,每次函数调用的信息保存在这个段, c 递归函数可以工作,递归函数每次调用自身时,就使用一个新的栈。

堆:通常在堆中动态分配内存。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值