Chinaunix首页 | 论坛 | 博客
  • 博客访问: 212788
  • 博文数量: 37
  • 博客积分: 3082
  • 博客等级: 中校
  • 技术积分: 387
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-14 13:59
文章分类
文章存档

2013年(1)

2012年(1)

2011年(2)

2010年(7)

2009年(1)

2008年(13)

2007年(12)

我的朋友

分类: LINUX

2008-10-29 15:03:48

其实很简单,Linux内核里有一篇文章讲到了(cpu_load.txt)。

原理吗,是由于CPU占用率计算的“漏洞”吧。
打个比喻,有工头每个小时来看一下你是否在干活,以此作为你干活多少的凭证。
假如你干了59分钟了,休息一分钟,突然工头来了,那么,你自认倒霉吧,你这一小时就白干了。
但是,另一工人比较聪明,前59分钟都在休息,但是最后1分钟,工头来了,他在干活,嘿嘿。

操作系统的调度器也是像那的笨工头一样,当然,调度器可不会一小时才check一次。
看cpu-load.txt的解释:
So how is this information collected?  Whenever timer interrupt is
signalled the kernel looks what kind of task was running at this
moment and increments the counter that corresponds to this tasks
kind/state.  The problem with this is that the system could have
switched between various states multiple times between two timer
interrupts yet the counter is incremented only for the last state.
下面的原理很简单,就是算出操作系统每次schedule的时间,然后让程序跑,在schedule前释放CPU资源。

/* gcc -o hog smallhog.c */
#include
#include
#include
#include
#define HIST 10

static volatile sig_atomic_t stop;

static void sighandler (int signr)
{
     (void) signr;
     stop = 1;
}
static unsigned long hog (unsigned long niters)
{
     stop = 0;
     while (!stop && --niters);
     return niters;
}

int main (void)
{
     int i;
     struct itimerval it = { .it_interval = { .tv_sec = 0, .tv_usec = 1 },
                             .it_value = { .tv_sec = 0, .tv_usec = 1 } };
     sigset_t set;
     unsigned long v[HIST];
     double tmp = 0.0;
     unsigned long n;
     signal (SIGALRM, &sighandler);
     setitimer (ITIMER_REAL, &it, NULL);

     hog (ULONG_MAX);
     for (i = 0; i < HIST; ++i) v[i] = ULONG_MAX - hog (ULONG_MAX);
     for (i = 0; i < HIST; ++i) tmp += v[i];
     tmp /= HIST;
     n = tmp - (tmp / 3.0);

     sigemptyset (&set);
     sigaddset (&set, SIGALRM);

     for (;;) {
         hog (n);
         sigwait (&set, &i);
     }
     return 0;
}

阅读(2515) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

qingruotianlan2010-01-27 09:25:57

你好,可以交个朋友吗,我也打算学习内核,希望以后多交流