今天在看ldd网卡驱动的时候,发现一个有趣的函数 printk_ratelimit()
他的主要做用和 prco文件系统下的,这两个接口有关系
printk_ratelimit
定义了消息之间允许的最小时间间隔。
printk_ratelimit_burst
定义消息数量
于是我机器上显示的就是 5s 内最多10条。
只是一个非常有意义的函数。 我们知道
ldd3 写道
hundreds or thousands of console messages per second is a good way to bog down
the system entirely and hide the real source of problems
the system entirely and hide the real source of problems
以前在做 服务器的时候 ,都是通过一个信号 重定向 a:打屏 b:dev/null c:文件 ,压力测试的时候打屏一直是瓶颈。我们来看看内核怎么处理大量的prink的。
#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \ \ struct ratelimit_state name = { \ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ .interval = interval_init, \ .burst = burst_init, .begin = // long \ }
这里的 interval_init 就是 5 , burst_init 是10
___ratelimit(&printk_ratelimit_state, func); /*func 就是当前执行的函数 *printk_ratelimit_state 就是那个初始化过的结构体*/
主要代码和分析如下
int ___ratelimit(struct ratelimit_state *rs, const char *func) { unsigned long flags; int ret; if (!rs->interval) return 1; /*这里当然要用 非阻塞的自选锁 ,保存并且禁止了本地中断 */ if (!spin_trylock_irqsave(&rs->lock, flags)) return 0; /*如果之前过了一个 打印时间点 就继续记录当前jiffies*/ if (!rs->begin) rs->begin = jiffies; /*这里其实 用了宏 time_after,用来判断当前的jiffies 有没有流逝过 打印时间点 */ if (time_is_before_jiffies(rs->begin + rs->interval)) { if (rs->missed) printk(KERN_WARNING "%s: %d callbacks suppressed\n", func, rs->missed); /*正好过了 就开始清零*/ rs->begin = 0; rs->printed = 0; rs->missed = 0; } /*没过的话 就继续看rs->printed 剩余的 *过了的话肯定打印*/ if (rs->burst && rs->burst > rs->printed) { rs->printed++;//打印计数 ret = 1; } else { rs->missed++;//忽略掉的 ret = 0; } /*恢复 */ spin_unlock_irqrestore(&rs->lock, flags); return ret; }
从以上的步骤可以看出,我们很容易在应用中,实现类似的功能。
#define DEBUG_ONE(a) { if( printk_ratelimit()){\ printf("*** %s DEBUG[%s:%d]: ", nowtime(time(NULL)), __FILE__, __LINE__); \ printf a; printf("\n");} \ }
#define time_after(now,after)宏
也很容易通过
static long get_time() { struct timeb tm; long Req_Begin=0,Req_Begin_ms=0,Res_Begin_Time=0; ftime(&tm); Req_Begin = tm.time; Req_Begin_ms = tm.millitm; Res_Begin_Time = ((long)Req_Begin*1000 +(long)Req_Begin_ms); return Res_Begin_Time; }
这样的函数实现。