c运行库

         在大多数程序员的眼中,一个程序的执行时从main函数开始的。可是实际上,事情的真相确实如此吗?其实之前的博客中已经提到在程序的main函数执行之前需要在进程堆栈中提前布置好main的参数。也就可以想见其实程序的执行不是从main函数开始,在main函数之前已经有代码在进行执行了。而这个执行的程序叫做入口函数或入口点,是运行库的一部分。

一个程序的执行的大体过程如下:

1os创建进城后,将程序的控制权交给入口函数

2、入口函数对运行库和程序执行的环境变量进行初始化,其中包括堆、I/O、线程、全局构造等

3、入口函数完成初始化之后,调用main函数,正式执行程序的主体部分。

4main执行结束后,返回入口函数,入口函数进行清理工作,包括全局变量析构、堆销毁、关闭I/O等。

首先说一下入口函数,其入口为_start,之后调用_libdc_start_main,对_libdc_start_main传入环境变量,main入口地址,main函数的参数等信息。由该函数完成对栈空间的布局。

其次在函数结束的时候调用exit,其循环调用atexit注册的函数,最后调用系统调用exit()。

 

C/C++的运行库在linux下为libc,其中包括入口函数,和各种标准库函数等。其主要功能包括:

1、启动与退出时环境变量和堆栈空间的管理

2、标准函数,c的标准库函数的实现

3I/O I/O封装的实现

4、堆,和堆内存的封装和实现。

关于堆的管理,程序在使用mallocnew的时候需要从堆中申请空间。该空间随意的申请和释放可以交给内核去做,这样频繁的系统调用会造成很大的系统开销,实际上堆是由运行库管理的,当堆空间不足时就使用brk()系统调用向os申请一块内存空间(注意此处仅仅涉及到虚拟内存)。关于堆的分配算法,其中包括空闲链表法和位图法等。

 

另外运行库是平台相关的,与os紧密结合,实质上是osC之间的抽象层。真正的c库提供和很多功能,不过向进程、线程的创建等需要由系统调用来完成,glibc中有一个可选的pthread库,用于创建线程是c运行库的超集。

linux的运行库包括两个部分,一部分是头文件,位于/usr/include中,一部分是库的二进制文件,二进制包括动态和静态两个版本,动态版本位于/lib/libc.so.6,静态版本位于/usr/lib/libc.a

 

我们也可以不使用glibc,仅仅通过系统调用来构建一个自己的c运行库,实现包括入口函数,进程相关操作,堆操作、文件字符操作等。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值