atomic_c: 原子操作的类型,确保多线程或多进程中数据的一致性,atomic_t对整数进行原子操作,它确保对atomic_c类型变量的操作是不可分割的
实现: cpu指令相关
#include <stdio.h>
#include <stdatomic.h>
atomic_int atomic_counter = ATOMIC_VAR_INIT(0); //宣称一个atomic_int类型的变量
void increment_counter(){
atomic_fetch_add(&atomic_counter, 1); //atomic_counter自动加1
}
int main(){
increment_counter();
printf("Counter: %d\n", atomic_load(&atomic_counter)); //安全加载atomic_counter当前值
return 0;
}
__init_or_module:一个宏,用于标记可在init期间或加载模块时使用的函数或数据结构。此宏通常用于在启动过程(内核初始化)和将模块动态加载到正在运行的内核中时需要执行或访问同一段代码的情况
__init:标有__init的函数或数据在内核初始化阶段(即内核启动时)使用。这些函数和数据结构通常在初始化后从内存丢弃,以回收在启动期间专门使用的内存
__init VS. __init_or_module: 当动态加载内核模块(使用insmod和modprobe)时,任何标有__init的函数或数据都无法访问,因为他们在启动后不再需要。因此,__init_or_module允许这些函数或数据结构在初始化启动阶段之后保留并可用
#include <linux/init.h>
struct my_data{
int value;
}__int_or_module;
void __init_or_module my_function(void){
printk(KERN_INFO "my_function called\n");
}
//my_data数据结构被标记为__init_or_module允许在初始化和模块加载期间使用
标记函数
通常使用特殊的宏或修饰符来标识函数特定的属性或行为。这些标记可以影响函数的生命周期、内存管理、链接属性以及编译器优化
- static修饰符: 静态函数只在当前文件内部调用,无法被其他文件使用。实现文件私有功能,同时避免全局明明空间的污染
- extern修饰符: 用于声明函数在其他文件中定义。虽然主要用于全局变量,但是也可用于函数声明,表明该函数在其他文件中定义,当前只是声明它的存在。通常在头文件中使用,以便多个源文件可以共享函数接口
- attribute((constructor)):
__attribute__((constructor))用于指定在程序启动时自动执行函数。这对于需要再main函数之前执行初始化工作的库函数或模块非常有用
void __attribute__((constructor)) my_init_function(void){
//initializayion code
}
- attribute((destructor)):
__attribute__((destructor))用于指定在程序退出时自动执行的函数,这对于清理工作(如释放资源、关闭文件等)非常有用
void __attribute__((destructor)) my_cleanup_function(void){
//code
}
- attribute((used))
__attribute__((used)):告诉编译器,几十函数备用被调用或没有被使用,也不要将其优化掉。在一些特定场景下(如内联汇编函数)非常有用