首次接触内核就遇到inline函数,当时也没放到心上,不就是个关键字。提高了程序的运行效率。
上课时,老师问具体如何实现以及什么情况下使用?
顿时我就不淡定了,且说的结果只有老师可以理解,我们的“听众”是,假设是对inline没有一点认识且首次接触linux内核,那么我们就要从最基本的情况说起。
首先给个例子:
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
};
上面的函数就用了inline关键字。inline在内核代码中很常见。使用时它要和函数体用在一块,而不是仅仅对函数声明前加个inline,那样没有实现inline的功能,仅仅就是个函数声明。
inline list_entry(struct list_head *list);//程序编译时仅仅认为是一个函数声明。
那么inline在函数调用中怎么实现?函数调用需要时间和空间开销,调用函数实际上将程序执行流程转移到被调函数中,被调函数的代码执行完后,再返回到调用的地方。这种调用操作要求调用前保护
好现场并记忆执行的地址,返回后恢复现场,并按原来保存的地址继续执行。对于较长的函数这种开销可以忽略不计,但对于一些函数体代码很短,又被频繁调用的
函数,就不能忽视这种开销。引入内联函数正是为了解决这个问题,提高程序的运行效率。
在程序编译时,编译器将程序中出现的内联函数的调用
表达式用内联函数的函数体来进行替换。由于在编译时将内联函数体中的代码替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间开销上不象
函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。
既然inline函数这么好,为什么不都用inline标示函数?
从上面可以看出,使用inline函数是以增加代码量来换取程序运行效率的。如果一个很大的程序,相对于增加代码量没有明显的运行效率的提高,我们就不会使用inline了,还有就是出现循环时,也不宜使用的。
使用内联函数时应注意以下几个问题:
(1) 在一个文件中定义的内联函数不能在另一个文件中使用。它们通常放在头文件中共享。
(2) 内联函数应该简洁,只有几个语句,如果语句较多,不适合于定义为内联函数。
(3) 内联函数体中,不能有循环语句、if语句或switch语句,否则,函数定义时即使有inline关键字,编译器也会把该函数作为非内联函数处理。
(4) 内联函数要在函数被调用之前声明。
大家以后在看内核代码时可以慢慢体会。
阅读(1352) | 评论(0) | 转发(0) |