Ubuntu Linux---GNU libc库( 四 )


(代码)(P74第8行)
void _init(void);
void _fini(void);
当一个库通过dlopen()动态打开或以共享库的形式打开时,如果_init在该库中存在且被输出出来,则_init函数会被调用(注释15) 。如果一个库通过dlclose()动态关闭或因为没有应用程序引用其符号而被卸载时,_fini函数会在库卸载前被调用 。当使用你自己的_init和_fini函数时,需要注意不要与系统启动文件一起链接 。可以使用GCC选项-nostartfiles做到这一点 。
上一页;;[1];[2];[3];[4][5];下一页
;但是,使用上面的函数或GCC的-nostartfiles选项并不是很好的习惯,因为这可能会产生一些意外的结果 。相反,库应该使用__attribute__((constructor))和__attribute__((destructor))函数属性来输出它的构造函数和析构函数 。如下所示:
(代码)(P74第21行)
void __attribute__((constructor)) x_init(void)
void __attribute__((destructor)) x_fini(void)
构造函数会在dlopen()返回前或库被装载时(注释16)调用 。析构函数会在这样几种情况下被调用:dlclose()返回前,或main()返回后,或装载库过程中exit()被调用时 。
3.6 系统调用
系统调用是用户程序请求内核为调用线程或进程提供具体服务的接口 。因为UNIX平台上的一些系统调用是与操作系统密切相关的,因此在Linux上可能不存在类似的系统调用 。这种情况下,就需要在Linux上实现一个包裹函数(wrapper) 。
Linux上系统调用的列表位于/usr/include/asm/unistd.h中 。本书的附录部分还对Linux和UNIX系统(如Solaris,HP-UX等)进行了并列比较 。
3.7 大页面支持
大页面的应用主要是用来提高应用程序的性能,该类应用程序需要分配大块内存并且频繁访问该内存 。性能的提高主要是通过减少地址转换缓冲器 (Translation Lookaside Buffer,简写作TLB,一块虚拟地址到物理地址转换的缓冲区)的未命中次数来实现的 。当TLB能够映射更大的虚拟内存范围时,即可减少TLB的未命中次数 。因为大部分现代的体系结构支持多种页面大小,上述方法也就可以实现了 。例如,Intel 32位架构支持4KB和4MB(PAE模式时为2MB)的页面;Itanium支持多种页面大小:4K,8K,64K,256K,1M,4M,16M和256M;SUN UltraSPARC支持8K,64K,512K和4M的页面;64位PowerPC(ppc64)支持4K,64K,16M和64G的页面 。本节内容将告诉应用程序开发人员如何使用Linux内核提供的大页面支持功能 。
Linux 2.6内核包含有内建的对hugetlbpage(Linux社区称呼大页面的专用术语)的支持 。内核配置成支持hugetlbpage时,命令cat /proc/meminfo的输出会显示出关于hugetlbpage的信息,如下例:
(代码)(P75倒数第8行)
HugePages_Total : 20
HugePages_Free : 20
Hugepagesize: 16384 KB
一种类型为hugetlbfs的文件系统也应该会出现在/proc/filesystems中 。在用户空间的应用程序能够使用hugetlbpage支持前,管理员应该先在内核中分配这些大页面 。/proc/sys/vm/nr_hugepages的内容显示的是内核中当前配置的大页面的个数 。如果要在系统上配置10个大页面,可以用下面的命令:
(代码)(P76第1行)
echo 10 > /proc/sys/vm/nr_hugepages
只有当系统中存在足够的连续物理内存时,分配请求才会成功;只有存在足够多的能够转回到正常内存池的空闲大页面时,释放请求才会成功 。用作hugetlbpage的页面在内核中作为保留页面而不能用作其他用途 。
应用程序开发人员有两种方法可以使用hugetlbpage支持:
1. 系统V共享内存系统调用(shmget,shmat)
2. mmap系统调用
同一个应用程序也可以两者都使用 。
下面的示例程序中,我们给出了如何使用上述系统调用来获得hugetlbpage支持 。这些程序来源于/usr/src/linux/Documentation/vm/hugetlbpage.txt 。

推荐阅读