关于Linux进程环境

进程的启动和终止

内核执行c程序时,利用exec函数调用一个特殊的启动例程,该启动例程丛内核中获取命令行参数和环境变量值。

进程终止的情况

5种正常终止的情况:

(1)从main函数返回; (2)调用exit; (3)调用_exit和_Exit函数; (4)最后一个线程调用pthread_exit; (5)最后一个线程从其启动例程返回;

3种异常终止情况

1)调用abort; (2)接到一个信号; (3)最后一个线程对取消请求做出响应; 进程启动和终止图

进程启动和终止图

atexit函数

一个进程最多可以登记32和函数(例如:signal函数),这些函数由exit函数自动调用。在程序终止时调用这些函数,形成终止处理程序,来进行结束进程前的收尾工作。而exit函数通过atexit函数的登记记录来判断调用哪些函数。

exit函数

此函数由ISO C 定义,其操作包括处理终止处理程序,然后关闭所有标准I/O流。需要注意的是,它不会处理文件描述符、多进程(父子进程)以及作业控制。

_e(E)xit函数
ISO C 定义这个函数的目的是为进程提供一种无需运行终止处理程序或信号处理函数的方法而终止程序。但ISO C 对标准I/O流是否进行冲洗,这取决于操作系统的实现。在unix中,是不进行冲洗的。 exit和_e(E)ixt函数的状态码

无论进程怎样结束,它都会在内核上执行同一段代码(由进程启动和退出图可知)。这段代码来关闭所有的文件描述符,释放所有的存储空间。

程序退出后,利用退出码告知该进程的父进程。父进程通过wait或waitpid函数来完成该子进程的善后工作(获取子进程相关信息 释放子进程占用资源)。若父进程没有处理子进程的退出状态,则子进程变成僵死进程。相反的,若父进程在子进程前终止,则子进程变成孤儿进程。孤儿进程会由1号进程(init进程)接收,大致过程如下:

(1)进程终止时,内核逐个检查所有活动的进程; (2)分析查找该终止进程的子进程; (3)将该进程的子进程的父进程ID改为1; wait和waitpid函数

程序正常或异常终止时,内核都会向父进程发送SIGNAL信号。子进程终止是异步事件,所以该信号也是异步信号。而该信号一般会被父进程默认忽略。或者提供一个信号处理函数来善后。wait和waitpid函数就是其中的信号处理函数的一部分。

wait和waitpid函数区别如下:

1wait会阻塞调用者进程等待直至第一个终止的子进程到来; (2waitpid可以通过参数设置,来实现调用者进程不阻塞,或选择要阻 塞等待的子进程;

这里的调用者指的是父进程

环境表和环境变量 环境表结构图

环境表结构

每个程序都接收到一张环境表

环境表也是一个字符指针数组

enrivon叫做环境指针

指针数组叫做环境表

各个指针指向的字符串叫做环境字符串

环境变量

unix内核并不检查环境字符串,它们的解释完全取决于各个应用进程

通常在一个shell启动文件中设置环境变量来控制shell的动作

修改或者增加环境变量时,只能影响当前进程以及其后(之前的不行)生成和调用的任何子进程的环境,但不能影响其父进程的环境

和环境变量相关的函数如下:

#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 这些函数如何修改环境表的

环境表和环境字符串通常存放在内存空间的高地址处(顶部)。所以在修改它的值时,内存是不能继续向高地址延伸;但又因为,它之下是各个栈帧,所以也不能向下延伸。如何修改它的值的过程如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13509.html