C语言中printk打印atomic_long_t的格式及取值异常问题求助
解决atomic_long_t类型值打印异常的问题
你的问题主要出在两个地方:循环结构错误和原子变量的读取方式不对,我来一步步帮你修正:
1. 先修复循环的问题
你写的for_each_zone(mzone);后面加了分号,这意味着循环体是空的,后面的l=mzone->vm_stat[NR_ACTIVE_ANON];是在循环结束后才执行的——此时mzone已经遍历完所有zone,指向了NULL或者无效的内存地址,所以你读取到的自然是0。必须把要执行的代码放在循环的大括号里。
2. 原子变量的正确读取方式
atomic_long_t是Linux内核封装的原子类型,它本质是一个结构体(类似typedef struct { long counter; } atomic_long_t;),不能直接用%lu或%ld直接输出——你直接传变量进去,其实是传了结构体的地址或者无效数据,肯定得不到正确结果。
内核提供了atomic_long_read()函数来安全读取这个原子变量的值,它需要传入atomic_long_t类型的指针,返回对应的long类型数值,之后你就可以用对应的格式符输出了。
修正后的代码示例
struct zone *mzone; // 遍历所有内存zone,注意大括号包裹循环体 for_each_zone(mzone) { // 直接读取zone中原子变量的值 long active_anon = atomic_long_read(&mzone->vm_stat[NR_ACTIVE_ANON]); // 打印时加上zone名称,方便区分不同zone的数值 printk(KERN_EMERG "Zone %s: NR_ACTIVE_ANON = %ld\n", mzone->name, active_anon); }
额外说明
如果你一定要先把值赋值给atomic_long_t变量再打印,也可以这么写:
struct zone *mzone; atomic_long_t l; for_each_zone(mzone) { l = mzone->vm_stat[NR_ACTIVE_ANON]; // 传入l的地址给atomic_long_read long val = atomic_long_read(&l); printk(KERN_EMERG "NR_ACTIVE_ANON: %ld\n", val); }
这样就能正确输出NR_ACTIVE_ANON的实际数值了。
内容的提问来源于stack exchange,提问作者king800820
相关产品推荐
相关产品推荐

