UNIX环境高级编程--7
进程环境
main函数:
C程序总是从main函数开始执行。main函数原型是:
int main(int argc, char *argv[]);
当内核执行C程序时(使用一个exec函数),在调用main前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址--这是由链接编译器设定的,而链接编辑器则由c编译器调用。启动例程从内核取得命令行参数和环境变量值然后按上述方式调用main函数做好安排。
进程终止:
8种方式使进程终止。其中5种为正常终止:
(1)从main返回;
(2)调用exit
(3)调用_exit或_Exit;
(4)最后一个线程从其启动例程返回
(5)从最后一个线程调用pthread_exit
异常终止3种:
(6)调用abort
(7)接到一个信号
(8)最后一个线程对取消请求做出相应
函数atexit:
ISO C规定,一个进程可以登记至多32个函数,这些函数将由exit自动调用。我们称这些函数为终止处理程序(exit handler),并调用atexit函数来登记这些函数。说白了就是当main函数将要结束的时候,自动会调用这些注册好的exit函数(和注册顺序相反)。
环境表:
char *envp[]:每个程序都有一个环境表。与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的c字符串的地址。
在历史上,大多数UNIX系统支持main函数代3个参数,第三个参数就是环境表。
C程序的存储空间布局:
(1)正文段(代码区)。CPU执行的机器指令部分。只读。
(2)初始化数据段。数据段。包含了程序中需明确附初始值的变量。例如C程序中任何函数之外的声明。都存储在数据段中。
int maxcount = 99;
(3)未初始化数据段。bss段。在程序开始执行前,内核将此段中的数据初始化为0或者空指针。
long sum[1000];
(4)栈。递归函数每次调用自身时,就用一个新的栈帧,因此一次函数调用实例中的变量集不会影响另一次函数调用实例中的变量。
栈底在0xC0000000之下开始,所以栈地址从高地址向低地址方向增长。
(5)堆。
共享库(动态链接库.so):
so == share object 在程序的链接时并不像静态库那样在拷贝使用函数的代码,只是做简单的标记。然后在程序开始启动的时候,动态加载所需要模块。所以,应用程序在运行的时候仍然需要共享库的支持。因此,共享库链接出来的文件比静态库要小很多,但是对.so文件的依赖更强。
假设源代码在foo.c文件离并且将创建成foo.so的共享库。中介对象文件叫foo.o。共享库可以包含多个对象文件。
创建共享库和链接可执行文件类似:先把源代码编译成目标文件,然后把目标文件链接起来,目标文件需要创建成位置无关码PIC(position-independent code)。
(1)创建PIC
略。。。
*静态库(静态链接库.a):
静态链接库是一些目标文件的集合,以.a结尾。在程序链接的时候使用,链接器会将程序中使用到函数的代码从库文件中拷贝到应用程序中。一旦链接完成,在执行的时候就不需要静态链接库了。由于使用静态链接的程序都需要拷贝所用函数,所以文件会比较大。
创建与应用:
(1)首先创建库文件libhello.c
#include
void hello()
{
printf("hello, welcome to library world!\n");
}
(2)创建头文件libhello.h
void hello();
(3)创建libhello静态库文件:
$ gcc -c libhello -o libhello.o
$ ar rcs libhello.a libhello.o
其中ar中的rcs的意思是: r表明将模块加入到静态库中,c表示创建静态库,s表示生产索引。
我们写一个测试程序:
$ cat test.c
#include
int main(void)
{
printf("use library hello.\n");
hello();
return 0;
}
(4)编译与链接:
$ gcc -c test.c -o test.o
$ gcc test.o -L. -lhello -o test
说明:-L.表示将当前目录加入到库搜索路径。默认的库搜索路径在/usr/lib目录下。
另外这里说明一下易混淆的参数-I,它表示搜索头文件的路径。这样gcc在查找头文件的时候会首先到-I指定的目录查找,然后才是系统默认目录。
-l参数: -lname表示库搜索目录下的libname.a 或者libname.so文件 ,这也是为什么库文件都以lib开头的原因之一。一个惯例嘛。当然了,如果你的库文件不是libhello,而是hello. 那就不能用-l参数编译了。 可以这样:
gcc test.o -L. hello.a -o test
注意: $gcc -L.-lhello test.o -o test 会出错!。
原因是: -l是链接器选项,必须要放到被编译文件的后面。 所以上面的命令中-lhello一定要放到 test.o的后面。
(5)运行:
$ ./test
use library hello.
hello, welcome to library world!
*动态加载库(So):
动态加载库(dynamicallyloaded (DL)libraries)指在程序运行过程中可以加载的函数库。而不是想共享库在程序启动的时候加载。DL对实现插件和模块化非常有用,因为他们可以让程序在允许时等待插件的加载。在linux中,二者的文件格式没有区别。
存储空间分配:
malloc calloc realloc , calloc为指定数量指定长度的对象分配存储空间。该空间中的每一位都初始化为0;
未声明函数的默认返回值为int。
free函数释放ptr指向的存储空间。被释放的空间通常被送入可用存储池。
替代的存储空间分配程序:
libmalloc、vamlloc、quickfit、jemalloc、TCMalloc
alloca:在栈上分配存储空间。没错 实在栈上!栈 之所以是栈 也不过是倒着用内存而已,但是却有奇效啊 , 各种数据结构逻辑顺序递归啊啥的都得以轻松实现,神了。
环境变量:
环境变量形式:name=value
UNIX内核并不查看这些字符串,他们的解释完全取决于各个应用程序。
setjmp longjmp函数:
在栈上函数调用栈可能会多层嵌套,当最底层发生错误时可以通过这两个函数直接返回最上层函数调用处,类似goto语句。
比如,在main中调用setjmp,并将所需要的信息记入变量jmpbuffer中并返回0,当在函数cmd_add中出出错时,则调用longjmp函数反绕到main函数的对应位置处。也就放弃了其他栈帧。
限制:
软限制:内核实际执行的限制,任何进程都可以将软限制设置为任意小于等于进程硬限制的值。
硬限制:可以在任何时候任何进程中设置,但只能由超级用户提起。
每天撸一点linux:
size cc :报告正文段、数据段和bss段的长度
因为c99(std=c99 : gcc的1999 ISO C拓展) 中不能声明无类型的主函数main所以会给警告,怎么忽略所有警告呢 : -w
UNIX环境高级编程--7的更多相关文章
- (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- multiple definition of `err_sys' 《UNIX环境高级编程》
本文地址:http://www.cnblogs.com/yhLinux/p/4079930.html 问题描述: [点击此处直接看解决方案] 在练习<UNIX环境高级编程>APUE程序清单 ...
- unix环境高级编程基础知识之第二篇(3)
看了unix环境高级编程第三章,把代码也都自己敲了一遍,另主要讲解了一些IO函数,read/write/fseek/fcntl:这里主要是c函数,比较容易,看多了就熟悉了.对fcntl函数讲解比较到位 ...
- (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (四) 一起学 Unix 环境高级编程(APUE) 之 系统数据文件和信息
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
随机推荐
- SVM简单上手示例
转载自 百度知道 id:风_南(https://zhidao.baidu.com/usercenter?uid=e9904069236f25705e799313) 转载只为方便学习复习,侵删. 在用s ...
- 洛谷 1062 NOIP2006普及T4 数列
[题解] 鲜活的水题..我们把数列换成k进制的,发现数列是001,010,011,100,101,110,111...,而第m项用k进制表示的01串刚好就是m的二进制的01串.于是我们预处理k的幂,把 ...
- Shiro_认证思路分析
[认证] 也就是登录. 1.获取当前的subject,调用SecurityUtils.getSubject() 2.测试当前的用户是否已经被认证,即是否登录.调用subject的isAuthentic ...
- FZU 2105 (线段树)
Problem 2105 Digits Count Problem Description Given N integers A={A[0],A[1],...,A[N-1]}. Here we h ...
- 工资(money)
(money/money.in/money.out) 时限1000ms 内存256MB 聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi.有m个结算工钱的时间,聪哥可以自由 ...
- JNI/NDK开发指南(三)——JNI数据类型及与Java数据类型的映射关系
转载请注明出处:http://blog.csdn.net/xyang81/article/details/42047899 当我们在调用一个Java native方法的时候.方法中的參数是怎样传递给C ...
- 例说linux内核与应用数据通信系列
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet.文章仅供学习交流,请勿用于商业用途] 本系列通过源代码演示样例解说linux内核态与用户态数据通信的各种方式: 例说 ...
- ubuntu 搭建 svn服务器,使用http方式访问
原文: http://blog.csdn.net/wobuxingfang/article/details/70835414 参考:http://www.cnblogs.com/zzugyl/p/36 ...
- Redis是单线程的
Redis是单线程的 学习了: http://blog.csdn.net/liupeng_qwert/article/details/77263187 https://www.cnblogs.com/ ...
- 编程算法 - 求1+2+...+n(函数继承) 代码(C++)
求1+2+...+n(函数继承) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 求1+2+...+n, 要求不能使用乘除法\for\whi ...