一 进程终止:

⼀个进程可以登记若⼲个(具体⾃⼰验证⼀下)个函数,这些函数由exit⾃动调⽤,这些函数被称为终⽌处理函数, atexit函数可以登记这些函数。 exit调⽤终⽌处理函数的顺序和atexit登记的顺序相反,如果⼀个函数被多次登记,也会被多次调⽤。

以下函数的调用时程序异常或者正常终止:

进程终⽌的⽅式有8种,前5种为正常终⽌,后三种为异常终⽌:
1 从main函数返回;
2 调⽤exit函数;
3 调⽤_exit或_Exit;
4 最后⼀个线程从启动例程返回;
5 最后⼀个线程调⽤pthread_exit;
6 调⽤abort函数;
7 接到⼀个信号并终⽌;

8 最后⼀个线程对取消请求做出响应。

exit()和_exit()以及_Exit()函数的本质区别是是否立即进入内核,_exit()以及_Exit()函数都是在调用后立即进入内核,而不会执行一些清理处理,但是exit()则会执行一些清理处理,这也是为什么会存在atexit()函数的原因,因为exit()函数需要执行清理处理,需要执行一系列的操作,这些终止处理函数实际上就是完成各种所谓的清除操作的实际执行体。

我们来验证下atexit的执行顺序:

#include <stdio.h>

#include <stdlib.h>

void func1(){

printf("func1");

}

void func2(){

printf("func2");

}

void func3(){

printf("func3");

}

int main(){

atexit(func1);

atexit(func2);

atexit(func3);

return 1;

}

执行结果:可以看到atexit函数的调用顺序和登记顺序是相反的

func3

func2

func1

二 命令行参数和环境表

在执行一个程序的时候,命令行参数可以传递给程序,方法就是通过main函数中的argc和argv参数

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

for(int j=0;j<argc;j++){

printf("argc[%d]:%s\n",j,argv[j]);

}

}

执行结果。第一个参数就是具体的命令行。

root@zhf-maple:/home/zhf/c_prj# ./chapter7 arg1 arg2 arg3

argc[0]:./chapter7

argc[1]:arg1

argc[2]:arg2

argc[3]:arg3

环境表:

每个程序都会接收到一张环境表。与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的C字符串的地址。全局变量environ则包含了该指针数组的地址

调用方法如下:

extern char **environ;

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

for(int i=0;environ[i]!=NULL;i++){

printf("%s\n",environ[i]);

}

return 1;

}

但是在UNIX系统中其实main函数带3个参数,其中第三个参数就是环境表地址

int main(int argc,char *argv[],char *envp[]){

for(int i=0;envp[i]!=NULL;i++){

printf("%s\n",envp[i]);

}

return 1;

}

如果想查询或者设置单个的环境变量该如何操作呢,这就需要用到操作环境变量的几个函数:

char *getenv(const char *name);

函数的返回值是name=value中value字符串的地址,若未找到则返回NULL。

int putenv(char *str);

int setenv(const char *name, const char *value, int rewrite);

int unsetenv(const char *name);

putenv的操作是将name=value字符串放到环境表中,若name存在,则先删除其原来的定义。
 setenv将name设置成value。如果在环境中name存在,当rewrite非0,则首先删除其现有的定义。当rewrite为0,则不删除其现有的定义(name不设置为新的value,而且也不出错);
unsetenv删除name的定义。即使name不存在也不出错。

来看下具体的使用方法:

通过设置name=“HOME”得到HOME的地址

void getenv_function(){

char *ret;

const char *name="HOME";

ret=getenv(name);

printf("%s",ret);

}

设置环境变量

char str[10]="sex=male";

void putenv_function(){

putenv(str);

}

setenv设置环境变量

void setenv_function(){

char name[10]="name";

char *str=(char *)malloc(20*sizeof(char));

const char *value="zhf";

memcpy(str,name,sizeof(name));

setenv(str,value,1);

}

putenv和setenv的区别:

setenv必须分配存储区,以便依据其参数创建name=value字符串。同时,putenv则无需将传送给它的参数字符串直接放到环境中。
注意:在使用putenv时,将存放在栈中的字符串作为参数传送给该函数时就会发生错误,其原因是,从当前函数返回时,其栈帧占用的存储区可能将被重用。

linux c编程:进程环境的更多相关文章

  1. Linux系统编程@进程通信(一)

    进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...

  2. linux系统编程-进程

    进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...

  3. Linux系统编程@进程管理(一)

    课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...

  4. [linux] C语言Linux系统编程进程基本概念

    1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...

  5. Linux/UNIX之进程环境

    进程环境 进程终止 有8种方式使进程终止,当中5中为正常终止,它们是 1)      从main返回 2)      调用exit 3)      调用_exit或_Exit 4)      最后一个 ...

  6. Linux多任务编程——进程

    进程编程常用函数 1--- fork pitd_t fork(void); 创建一个新的子进程,其父进程为调用 fork() 函数的进程: 返回值:成功:子进程返回 0,父进程返回 子进程 PID:失 ...

  7. Linux下的进程环境

    僵尸进程.孤儿进程.守护进程.进程组.会话.前台进程组.后台进程组 1,僵尸进程 子进程结束,父进程没有明确的答复操作系统内核:已收到子进程结束的消息.此时操作系统内核会一直保存该子进程的部分PCB信 ...

  8. Linux系统编程——进程替换:exec 函数族

    在 Windows 平台下,我们能够通过双击运行可运行程序,让这个可运行程序成为一个进程.而在 Linux 平台.我们能够通过 ./ 运行,让一个可运行程序成为一个进程. 可是.假设我们本来就执行着一 ...

  9. Linux系统编程@进程管理(二)

    1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...

  10. UNIX环境高级编程——进程环境

    一.main函数 C程序总是从main函数开始.当内核执行C程序时,在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址--这是由连接编译器设置的,而连接编译器则由 ...

随机推荐

  1. python——变量作用域及嵌套作用域

    ----------------------------------------------------------------------------- 前言-------------------- ...

  2. CDN原理实现详情

    CDN真是个好东西,但是究竟是怎么实现的呢, 学习下吧 首先浏览器发起请求 Dns解析寻找服务器资源 使用CDN加速的内容会被放到不同的服务器上 根据用户的请求来判断 -- 算了表达不清楚,看图吧! ...

  3. 人不在囧途 便携式3G上网设备+套餐推介

    来源: http://network.pconline.com.cn/317/3174920_all.html [PConline资讯]过年回家,本该是再高兴不过的事,可一想到要在路上颠簸数十个小时, ...

  4. 解密和解压浏览器上加密的js文件

    F12 -> 进入Sources -> 找到任意一个加密的js文件,如图 点击最下方的 {} 即可解压

  5. 在SDL中显示GBK点阵汉字

    大家注意到没有,RA2的中文版本使用的是GBK点阵字库,这样做有一个好处:不管玩家是用的简体还是繁体都能识别显示的文字. GBK的意思大概是“国家标准汉字扩展字符集”吧,记不清了.但它的确是个好东东, ...

  6. Httpclient 实现带参文件上传

    这里直接贴出的是我封装好的doPostFile方法,httpclient 的版本是3.1. public static String doPostFile(String url, Part[] par ...

  7. xcode下载低版本模拟器速度缓慢解决方案

    随着苹果系统的更新和迭代,现在app开发中需要适配的除了需要适配屏幕尺寸以外,还需要适配系统版本.系统版本测试如果有条件可以使用各种系统版本的真机进行适配,如果没有这个条件,也可以采用xcode的模拟 ...

  8. [译]GLUT教程 - 改变窗体大小

    Lighthouse3d.com >> GLUT Tutorial >> Basics >> Resizing the Window 上一章的例子创建了两个窗体,命 ...

  9. 卸载Linux自带openjdk

    1.查看自带jdk版本   java -version 2.查看   rpm  -qa | grep java 显示如下信息: java-1.4.2-gcj-compat-1.4.2.0-40jpp. ...

  10. jfreechart折线图 demo

    public class ChartUtil { public static ChartUtil chartUtil; private RoomViewsDataService roomViewsDa ...