UNIX进程的环境

在学习进程之前,先来了解下进程的执行环境。

main函数

进程总是从main函数开始执行的,我们编程时,程序运行也是从main函数运行的,它的原型如下:

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

argc是命令行参数的数目,argv是指镇数组,即指向指针的指针,可以写代码测试一下:

#include<stdio.h>

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

{

int i;

for(i=0; i<argc; i++)

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

exit(0);

}

输出:

linux:/home # ./test this is a test program

argv[0]:./test

argv[1]:this

argv[2]:is

argv[3]:a

argv[4]:test

argv[5]:program

在调用main函数之前,内核先调用一个特殊的启动例程,它从内核取得命令行参数和环境变量的值,可执行程序文件将此启动例程指定为程序的起始地址。内核使用exec函数来启动C程序。

进程终止

有5种方式可以终止进程

(1)正常终止

(a)从main函数返回

(b)调用exit

(c)调用_exit

(2)异常终止

(a)调用abort

(b)由一个信号终止

在上面的正常终止中有exit和_exit,区别在于:_exit调用后立即进入内核;而exit则会先执行一些清除工作(包括调用执行各种终止处理程序,关闭所有标准I/O流等),然后在进入内核。它们定义如下:

#include<stdlib.h>

void exit(int status);

#include<unistd.h>

void _exit(int status);

使用了不同的头文件,因为exit是右ANSI C说明的,而_exit是由POSIX.1说明的。

atexit函数

我们可以在进程中登记一些函数(最多32个),这些函数由exit调用。这样的函数叫做终止处理程序(exit handler),有atexit函数来登记。这点看起来有点像类的析构函数。

#include<stdlib.h>

int atexit(void (*func)(void));

其参数是一个函数地址。exit调用顺序与登记顺序相反,先登记后调用(像栈),同一个函数可以被登记多次。

环境表

进程的运行都有一个环境,环境的信息存储在环境表里面。环境表是一个字符指针数组,其中每个指针包含一个以NULL结束的字符串的地址。全局变量environ包含了该指针数组的地址:

extern char **environ;

程序的存储空间布局

C程序由以下几部分组成:

正文段:也叫代码段,是CPU执行的机器指令。正文段一般可以共享的,且是只读的。

初始化数据段:也叫做数据段,包含程序中已经初始化的全局变量和静态变量。

非初始化数据段:也叫做bss段,包含未初始化的全局变量和静态变量,在程序执行之前有内核初始化为0。不在代码中存储器初始值,可以减小代码的大小。

栈:自动存储变量以及每次函数调用时所需保存的信息都放在此段中。每次函数调用时,其返回地址、以及寄存器中的变量都放在栈中。新被调的函数在栈上为其自动和临时变量分配存储空间。

堆:进行动态分配的变量。需要手动释放。堆位于未初始化数据段的顶和栈底之间。

存储器的分配:

可以参考这里

setjmp和longjmp

在C语言中,可以使用goto语言(虽然不建议使用),但是goto语句不能跳跃函数。执行这个跳转功能的函数时setjmp和longjmp。这两个函数对于处理发生在很深的嵌套调用中的出错情况非常好用。递归调用返回时只能返回到上一层函数,这两个函数可以使其跳出递归调用。

UNIX进程的环境

时间: 2024-10-09 12:48:30

UNIX进程的环境的相关文章

[APUE]UNIX进程的环境(下)

一.共享库 共享库使得可执行文件中不再需要包含常用的库函数,而只需在所有进程都可存取的存储区中保存这种库例程的一个副本.程序第一次执行的时候或第一次调用某个库函数的时候,用动态链接方法将程序与共享库函数相链接,这减少了每个可执行文件的长度,但增加了一些运行时间开销.另一个优点就是可以用库函数的新版本来替换老版本而无需对该库的程序重新链接编译. 不同的系统使用不同的方法说明程序是否需要使用共享库.比较典型的有cc和ld命令的可选项. 二. 存储器分配 ANSI C说明了三个存储空间动态分配的函数(

进程篇(1: 进程运行环境)--请参照本博客“操作系统”专栏

2014年5月30日  下午1:40:59 1. Unix 进程执行环境: 1.1 终止处理程序: ISO C 规定,一个程序可以登记多达32个函数,这些函数将由exit自动调用.我们称这些函数为终止处理程序(exit handler),并调用atexit函数来登记这些函数.该函数的原型如下: 1 #include <stdlib.h>2 3 int atexit(void (*function)(void)); exit调用这些终止程序的顺序与他们登记时的顺序相反(先登记后调用).同一个函数

Linux系统开发 4 进程资源 环境 fork()子进程 wait() waitpid()僵尸 孤儿进程

<大纲> Linux系统编程 进程资源上限 进程环境变量 进程获取/修改环境变量 创建子进程fork() 最大进程数测试 程序的设置用户ID/组ID/黏住位 exec簇函数,执行程序覆盖堆栈 fork 与execl函数在一起 exec() 与主程序同一个PCB 僵尸进程 wait()回收僵尸进程 证明:父子进程同组pid waitpid() 非阻塞等待子线程发生变化 孤儿进程演示[父进程已经结束,子进程还在运行] 进程资源上限值 [email protected]:~$ cat /proc/s

UNIX进程

一.UNIX进程环境 在学习UNIX进程工作原理时,我们应该先了解一下UNIX进程的基本环境是怎么样的,首先从main函数开始. 1.main函数 int main(int argc, char *argv[]); 相信main函数是我们非常熟悉的一个函数,它是C程序执行的入口函数.其中,argc是命令行参数的数目,agrv是指向参数的各个指针所构成的数组,而ISO/C和POSIX.1都要求argv[argc]是一个空指针. 当内核使用一个exec函数执行C程序时,在调用main函数前先调用一个

unix网络编程环境搭建

unix网络编程环境搭建 新建 模板 小书匠 1.点击下载源代码 可以通过下列官网中的源代码目录下载最新代码: http://www.unpbook.com/src.html 2.解压文件 tar -xzvf upv13e.tar.gz 3.上传至阿里云 本人本地已经配置好,这次实验是将环境搭建至云服务器中. scp -r unpv13e [email protected]120.76.140.119:/root/program/unp // -r 上传文件夹  4.编译文件 cd unpv13

UNIX进程之间传递文件描述符recvmsg与sendmsg

socketpair: 功能:创建一个全双工的流管道 原型 int socketpair(int domain, int type, int protocol, int sv[2]); 参数 domain: 协议家族 type: 套接字类型 protocol: 协议类型 sv: 返回套接字对 返回值:成功返回0:失败返回-1 ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); ssize_t recvmsg(int

记录一次配置unix网络编程环境的过程和遇到的问题

记录一次搭建unix网络编程环境过程中遇到的问题和总结 计算机环境虚拟机 linuxmint-18-xfce-64bit 1.打开unix网络编程.iso 把目录下的文件夹复制到某一目录,修改权限,可命令可鼠标操作. 2. [email protected] ~/unix/unpv13e $ sudo su [sudo] s 的密码: ss-Linux unpv13e # ./configure checking build system type... x86_64-unknown-linux

Linux/UNIX进程间的通信(1)

进程间的通信(1) 进程间的通信IPC(InterProcessCommunication )主要有以下不同形式: 半双工管道和FIFO:全双工管道和命名全双工管道:消息队列,信号量和共享存储:套接字和STREAMS 管道 pipe函数 当从一个进程连接到另一个进程时,我们使用术语管道.我们通常是把一个进程的输出通过管道连接到另一个进程的输入. 管道是由调用pipe函数创建的: #include<unistd.h> int pipe(intpipefd[2]); 经由参数pipefd返回两个文

UNIX世界的环境变量

UNIX世界的环境变量 各种Local环境变量 名称 说明 LANG 未设置任何LC_xxx变量时所使用的默认值 LC_ALL 用来覆盖掉所有其他LC_xxx变量的值 LC_COLLATE 使用所指定地区的排序规则 LC_CTYPE               使用所指定地区的字符集(字母.数字.标点符号等) LC_MESSAGES         使用所指定地区的响应与信息: 仅POSIX适用 LC_MONETARY         使用所指定地区的货币格式 LC_NUMERIC