unix编程以及xv6系统浅谈(四)进程环境

254 阅读2分钟

​ 在main前调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址,启动例程会从内核取得命令行参数和环境变量值,然后为调用mian做好准备。

4.1 进程终止

​ 有8种啊方式使进程终止,前5种为正常终止,如下

​ (1)从main返回,等效于调用exit()

​ (2)调用exit函数

​ (3)调用_exit和 _Exit

​ (4)最后一个线程从启动例程返回

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

​ 后面3种如下,为异常终止方式

​ (1)调用abort

​ (2)接到一个信号

​ (3)最后一个线程对取消请求做出相应破

​ 一般从main返回后立即调用exit函数

​ exit(main(argc,argv));

退出函数

void exit(int stat)
  	先执行一些自定义的或者内核定义的函数,再必须执行一个标准IO库的清理关闭操作,将所有的打开流调用fclose函数
  	注意,直接return main函数也是会调用exit函数的
  	return 0 == exit(0)
void _Exit(int stat)
void _exit(int stat)
    立即进入内核,不做处理

​ 一个进程可以登记多到32个函数,这下函数将在exit自动调用,可以通过atexit函数来登记这些函数

int atexit(void (*func)(void))
    成功则返回0.否则返回非0
    参数是一个函数地址,调用这些函数的顺序与登记的时候相反
    一般函数地址直接函数名就可。

4.2 命令行参数和环境参数

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

​ argc从0开始,argv[argc]==NULL

​ argv[0]=调用的命令,后面的才是参数

可以写作

for(i=0;argv[i]!=NULL;i++)

​ 同样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的c字符串的地址,全局变量environ则包含了该指针数组的地址

​ extern char** environ;

每个环境字符串类型于"PATH=:abcd\0"

char* getenv(const char* name)
	返回与name关联的value指针,未找到则返回NULL
int putenv(char* str)
    成功则返回0,否则返回非0
    取形式为"name=value\0"格式的字符串放入环境表中,若name已经存在则删除原来的定义
int setenv(const char* name,const char *value,int rewrite)
    将name设置为value,如果环境表中name已经存在,则
    	rewrite=0	不删除现有定义
    	rewrite=1	删除现有的定义
int unsetenv(const char* name)
    删除name的定义,即使未定义也不会出错