《LINUX实操:关于Linux进程环境》要点:
本文介绍了LINUX实操:关于Linux进程环境,希望对您有用。如果有疑问,可以联系我们。
内核执行c法式时,利用exec函数调用一个特殊的启动例程,该启动例程丛内核中获取命令行参数和环境变量值.
5种正常终止的情况:
(1)从main函数返回;
(2)挪用exit;
(3)挪用_exit和_Exit函数;
(4)最后一个线程挪用pthread_exit;
(5)最后一个线程从其启动例程返回;
3种异常终止情况
(1)调用abort;
(2)接到一个信号;
(3)最后一个线程对取消哀求做出响应;
一个进程最多可以登记32和函数(例如:signal函数),这些函数由exit函数自动调用.在法式终止时调用这些函数,形成终止处理法式,来进行结束进程前的收尾工作.而exit函数通过atexit函数的登记记录来判断调用哪些函数.
此函数由ISO C 定义,其操作包含处理终止处理程序,然后关闭所有标准I/O流.需要注意的是,它不会处理文件描述符、多进程(父子进程)以及作业控制.
无论进程怎样结束,它都会在内核上执行同一段代码(由进程启动和退出图可知).这段代码来关闭所有的文件描述符,释放所有的存储空间.
程序退出后,利用退出码告知该进程的父进程.父进程通过wait或waitpid函数来完成该子进程的善后工作(获取子进程相关信息 释放子进程占用资源).若父进程没有处理子进程的退出状态,则子进程酿成僵死进程.相反的,若父进程在子进程前终止,则子进程酿成孤儿进程.孤儿进程会由1号进程(init进程)接收,大致过程如下:
(1)进程终止时,内核逐个检查所有活动的进程;
(2)分析查找该终止进程的子进程;
(3)将该进程的子进程的父进程ID改为1;
程序正常或异常终止时,内核都会向父进程发送SIGNAL信号.子进程终止是异步事件,所以该信号也是异步信号.而该信号一般会被父进程默认忽略.或者提供一个信号处理函数来善后.wait和waitpid函数便是其中的信号处理函数的一部分.
wait和waitpid函数区别如下:
(1)wait会阻塞调用者进程期待直至第一个终止的子进程到来;
(2)waitpid可以通过参数设置,来实现调用者进程不阻塞,或选择要阻
塞期待的子进程;
这里的调用者指的是父进程
和环境变量相关的函数如下:
#include<stdlib.h>
char *getenv(const char *name);
返回值:指向与name关联的value的指针;若未找到,返回NULL
int putenv(char *str);
返回值:若成功,返回0;若出错,返回非0
int setenv(const char *name, const char *value,
int rewrite);
int unsetenv(const char *name);
两个函数返回值:若成功,返回0;若出错,返回-1
环境表和环境字符串通常存放在内存空间的高地址处(顶部).所以在修改它的值时,内存是不克不及继续向高地址延伸;但又因为,它之下是各个栈帧,所以也不克不及向下延伸.如何修改它的值的过程如下:
(1)改动环境表
1)新value <= 旧value,直接覆盖旧value的存储空间
2)新value >= 旧value,调用malloc函数,在堆区开辟新的存储空间,
将新value复制到这里,再将这片存储区首地址写到环境表相应的地位处.
(2)新增环境表
1)新增一个环境变量,调用malloc函数开辟新的存储空间,将本来的环
境表复制到该存储区,其次再添加一个环境变量,然后在尾部赋值为NULL,
最后将environ指向该区域;
2)在 1)过程的基础上,调用realloc函数,多次添加环境变量;
注意:以这种方式修改的环境变量只在当下程序运行时有效,当程序结束时,相应的存储区被系统回收,这些修改就会失效.
#include<stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nojy, size_t size);
void *realloc(void *ptr, size_t newsize);
3个函数返回值:若成功,返回非空指针;若出错,返回NULL
注意:这些动态分配的函数一般在分配存储空间时,会比要求的大.因为在开辟空间的前后部分存储记录管理信息.因此,在使用时,千万不要越界拜访,以免造成不可预知的后果.
在c语言中,goto语句是不克不及跨函数跳转的.尤其是在函数深层调用时的跳转需求,在出错处理的情况下非常有用.
#include<setjmp.h>
int setjmp(jmp_buf env);
返回值:若直接调用,返回0;若从longjmp返回,返回非0
void longjmp(jmp_buf env, int val);
变量值回滚问题:自动变量和寄存器变量会存在回滚现象.利用volatile属性来避免此类情况的产生.(在给变量赋值时,赋的值回首先存储在内存(存储器变量)中,然后在由cpu取走,存储在cpu的寄存器上(寄存器变量).在做系统优化时,那些频繁使用的变量,会直接存储到寄存器中而不经过内存.)
在调用setjmp函数时,内核会把当前的栈顶指针保存在env变量中,所以在调用longjmp函数返回该位置时,全局变量、静态变量、易失变量和自动变量如果在调用setjmp和longjmp函数之间它们的值被修改过,是不会回滚到setjmp函数调用之前的值(当然,编译器将auto变量优化为寄存器变量除外).因为,这些存储器变量的值是存储在内存相应的段中,回到原先栈顶状态时,同样拜访的还是原先的内存空间.
然而,对于寄存器变量来说,首先要明确一点:寄存器变量是用动态存储的方式.意思是寄存器变量的值可能存在分歧的寄存器中.如果在调setjmp和longjmp函数之间它们的值被修改过,这个值可能不会存到setjmp之前的对其赋值的寄存器中,而在调用longjmp函数后,又回到了调用setjmp函数时的状态.这个时候再读取寄存器变量的值时,读到的是原先那个寄存器中存储的值而不是修改过的那个寄存器中存储的值,所以出现的回滚现象.
本文永远更新链接地址:
维易PHP培训学院每天发布《LINUX实操:关于Linux进程环境》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。
转载请注明本页网址:
http://www.vephp.com/jiaocheng/7683.html