昨天在和前辈交流的过程中被前辈一个问题问住了:函数名前面的双下划线有什么用?
我回答的是带下划线的是系统内部函数,我们尽量不要使用,我们如果要使用的话要使用同名,但不带下划线的函数。
但是前辈说我说的不太对,或者不太完全,下来后我查询了一下,确实我理解的好像有错误!
我的理解来源:

通过上图我们发现带下划线的函数是经过处理或未被处理的同名函数,这样的话我们不难想到,带下划线的函数名是内部用的,你如果要想使用的话就要使用不带下划线的函数名。
因为前辈问的是双下划线的作用,结果我回答成了的单下划线的作用了,非常尴尬。那咱们就一起来看看双下划线有什么作用吧!
在内核API函数具有这种名称的,通常都是一些接口的底层函数,应该谨慎使用。实质上,这里的双下划线就是要告诉程序员:谨慎调用,后则后果自负。
但是有些带下划线的还有其他含义,比如:__init __exit
__init 的宏定义是在 init.h 文件中定义的,我们可以找到 __init 的定义原型:
#define __init __section(".init.text")
关于__init的解释,在Linux内核代码注释中有对这方面进行解释:
These macros are used to mark some functions or initialized data (doesn’t apply to uninitialized data) as initialization functions. The kernel can take this as hint that the function is used only during the initialization phase and free up used memory resources after.
这句话的翻译如下:
这些宏用于将一些函数或初始化数据(不适用于未初始化的数据)标记为“初始化”函数。内核可以将此作为仅在初始化阶段使用该函数的提示,并在之后释放使用的内存资源。
所以我们现在就知道了__init的作用了,那么怎么使用__init呢?Linux内核源码中也给了我们使用方法:
You should add __init immediately before the function name.
这句话的翻译:
你应该在函数名之前加上__init
例如下面比较常见的使用方法:
static int __init brd_init(void)
{
}
static void __exit brd_exit(void)
{
}
上面两个函数相信大家学习过Linux驱动的话应该都不陌生吧!这就是整个驱动文件的出入口函数,在出入口函数前面加入__init和__exit是为了高数编译器这个是我的入口(出口)函数,只需要在驱动装载(卸载)的过程中调用一次,且调用完之后需要在合适的时间释放掉。
如果我们想要某个函数只在装载或卸载的时候执行一次,那么我们就可以在定义函数的时候在函数名字之前加上__init或__exit。当然一般我们并不会这么做,我们常用的做法是将我们需要在装载驱动过程中执行(但是不一定只执行一次)的函数放在入口函数中。
上面我们已经知道了 __init 的宏定义后理解 __exit 宏定义相对就比较简单了。__exit 宏定义表示该函数只在驱动卸载时执行一次,使用方法和 __init 是一样的,这里就不再过多讨论了。
以上就是我对于Linux内核中 __ 的理解,由于自己才疏学浅,如果有理解有误的地方,还望各位大佬们进行批评指正!