linux c编程:进程环境
一 进程终止:
⼀个进程可以登记若⼲个(具体⾃⼰验证⼀下)个函数,这些函数由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编程:进程环境的更多相关文章
- Linux系统编程@进程通信(一)
进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统 ...
- linux系统编程-进程
进程 现实生活中 在很多的场景中的事情都是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的: 如下是一段视频,迈克杰克逊的一段视频: http://v.youku.com ...
- Linux系统编程@进程管理(一)
课程目标: 构建一个基于主机系统的多客户即时通信/聊天室项目 涉及的理论知识 进程控制:僵尸进程/孤儿进程.进程控制.守护进程... 进程间通信:管道.命名管道.信号... 多线程编程: 锁.信号量. ...
- [linux] C语言Linux系统编程进程基本概念
1.如果说文件是unix系统最重要的抽象概念,那么进程仅次于文件.进程是执行中的目标代码:活动的.生存的.运行的程序. 除了目标代码进程还包含数据.资源.状态以及虚拟化的计算机. 2.进程体系: 每一 ...
- Linux/UNIX之进程环境
进程环境 进程终止 有8种方式使进程终止,当中5中为正常终止,它们是 1) 从main返回 2) 调用exit 3) 调用_exit或_Exit 4) 最后一个 ...
- Linux多任务编程——进程
进程编程常用函数 1--- fork pitd_t fork(void); 创建一个新的子进程,其父进程为调用 fork() 函数的进程: 返回值:成功:子进程返回 0,父进程返回 子进程 PID:失 ...
- Linux下的进程环境
僵尸进程.孤儿进程.守护进程.进程组.会话.前台进程组.后台进程组 1,僵尸进程 子进程结束,父进程没有明确的答复操作系统内核:已收到子进程结束的消息.此时操作系统内核会一直保存该子进程的部分PCB信 ...
- Linux系统编程——进程替换:exec 函数族
在 Windows 平台下,我们能够通过双击运行可运行程序,让这个可运行程序成为一个进程.而在 Linux 平台.我们能够通过 ./ 运行,让一个可运行程序成为一个进程. 可是.假设我们本来就执行着一 ...
- Linux系统编程@进程管理(二)
1.创建守护进程(Deamon) 守护进程的概念与作用 后台服务程序 – 系统服务,进程名字往往以’d’结尾,生存周期比较长(系统装入时启动,关闭时候终止.系统装入两种启动方式:1从启动脚本.etc/ ...
- UNIX环境高级编程——进程环境
一.main函数 C程序总是从main函数开始.当内核执行C程序时,在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址--这是由连接编译器设置的,而连接编译器则由 ...
随机推荐
- EF.Reverse.POCO.Core.ttinclude"
<#@ include file="EF.Reverse.POCO.Core.ttinclude" #> <# // v2.18.1 // Please make ...
- FizzBuzz and Fibonacci优化
***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...
- JMeter接口测试中文乱码问题总结
在测试过程中遇到了请求json串中文乱码,所以查看了这篇文章,将字符集修改后,乱码问题已经处理. 转载http://blog.csdn.net/qing_java/article/details/69 ...
- ionic准备之angular基础——dom操作相关(6)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux组件封装(二)中条件变量Condition的封装
条件变量主要用于实现线程之间的协作关系. pthread_cond_t常用的操作有: int pthread_cond_init(pthread_cond_t *cond, pthread_conda ...
- 第14章5节《MonkeyRunner源代码剖析》 HierarchyViewer实现原理-装备ViewServer-查询ViewServer执行状态
上一小节我们描写叙述了HierarchyViewer是怎样组建ADB协议命令来实现ViewServer的port转发的.在port转发设置好后,下一个要做的事情就是去检測目标设备端ViewServer ...
- iOS项目开发实战——使用同步请求获取网页源码
网络请求一般分为同步请求和异步请求,同步请求假设訪问时间过长,会造成界面卡死状态,用户体验不是非常好.可是请求速度较快的话,也能够考虑使用同步訪问.如今先来学习同步訪问. (1)在viewDidLoa ...
- 【HTML5】元素<head>的使用
功能描述 在新建的页面<head>元素中,加入该元素所包含的各类标签,并定义超级链接的样式.当单击"请点击我"标签时,并展示相应效果并进入<base>元素设 ...
- 早来的圣诞礼物!--android 逆向菜鸟速參手冊完蛋版
我的说明: 让老皮特整理了这么长时间这个手冊,心里挺过意不去的,回头我去深圳带着他女儿去游乐场玩玩得了,辛苦了.peter! 太多的话语,也描写叙述不出这样的感觉了,得找个时间.不醉不归... 注:下 ...
- CALayer的contentsRect
contentsRect 想像下contentsRect作为层内容的可视区域.内容的矩形区域(x,y,width,height)也是绑定到层的框架上的.contentRect是一个比例值,而不是屏幕上 ...