UNIX环境高级编程(pdf+epub+mobi+txt+azw3)
第7章 进程环境
7.1 引言
下一章将介绍进程控制原语,在此之前需先了解进程的环境。本章中将学习:当程序执行时,其main函数是如何被调用的;命令行参数是如何传递给新程序的;典型的存储空间布局是什么样式;如何分配另外的存储空间;进程如何使用环境变量;进程的各种不同终止方式等。另外,还将说明longjmp和setjmp函数以及它们与栈的交互作用。本章结束之前,还将查看进程的资源限制。
7.2 main函数
C程序总是从main函数开始执行。main函数的原型是:
int main(int argc, char *argv[]);
其中,argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组。7.4 节将对命令行参数进行说明。
当内核执行C程序时(使用一个exec函数,8.10节将说明exec函数),在调用main前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址——这是由连接编辑器设置的,而连接编辑器则由C编译器调用。启动例程从内核取得命令行参数和环境变量值,然后为按上述方式调用main函数做好安排。
7.3 进程终止
有8种方式使进程终止(termination),其中 5种为正常终止,它们是:(1)从main返回;
(2)调用exit;
(3)调用_exit或_Exit;
(4)最后一个线程从其启动例程返回(11.5节);
(5)从最后一个线程调用pthread_exit(11.5节)。
异常终止有3种方式,它们是:
(6)调用abort(10.17节);
(7)接到一个信号(10.2节);
(8)最后一个线程对取消请求做出响应(11.5节和12.7节)。
在第11章和第12章讨论线程之前,我们暂不考虑专门针对线程的3种终止方式。
上节提及的启动例程是这样编写的,使得从main返回后立即调用exit函数。如果将启动例程以C代码形式表示(实际上该例程常常用汇编语言编写),则它调用main函数的形式可能是:
exit(main(argc, argv));
1.退出函数
3个函数用于正常终止一个程序:_exit和_Exit立即进入内核,exit则先执行一些清理处理,然后返回内核。
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
我们将在8.5节中讨论这3个函数对其他进程(如正在终止进程的父进程和子进程)的影响。
使用不同头文件的原因是exit和_Exit是由ISO C说明的,而_exit是由POSIX.1说明的。
由于历史原因,exit 函数总是执行一个标准 I/O 库的清理关闭操作:对于所有打开流调用fclose函数。回忆5.5节,这造成输出缓冲中的所有数据都被冲洗(写到文件上)。