Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1468729
  • 博文数量: 842
  • 博客积分: 12411
  • 博客等级: 上将
  • 技术积分: 5772
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-14 14:43
文章分类

全部博文(842)

文章存档

2013年(157)

2012年(685)

分类: LINUX

2012-03-06 13:35:20

计算机中的时间

写在前面:时钟可以说是计算机的心脏,它是分时系统的基础。如果时钟反应到应用程序的层面,就是时间,很多应用程序都会涉及到时间处理。本文就来讨论一下计算机中的时钟与时间。

1、操作系统中的时间
在Unix/Linux系统中,有两个不同的时间:日历时间和进程时间。
(1)日历时间:
有些书上又叫系统时间。该值是自1970年1月1日00:00:00以来国际标准时间(U T C)所经过的秒数累计值(早期的手册称U T C为格林尼治标准时间)。在PC/AT微机系统中,支撑该时间的硬件是实时钟RT(Real Time)电路。操作系统在系统初始化的过程中,会从该电路中读取该时间,并保存在内核变量中。
来看看Linux1.0中相关的代码

//kernel/time.c
extern long kernel_mktime(struct mktime * time);
//初始化时间
void time_init(void)
{
    
struct mktime time;
    
int i;

    

    

    
for (i = 0 ; i < 1000000 ; i++)    
        
if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
            
break;
    
for (i = 0 ; i < 1000000 ; i++)    
        
if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
            
break;
    
do { 
        time.sec 
= CMOS_READ(RTC_SECONDS);
        time.min 
= CMOS_READ(RTC_MINUTES);
        time.hour 
= CMOS_READ(RTC_HOURS);
        time.day 
= CMOS_READ(RTC_DAY_OF_MONTH);
        time.mon 
= CMOS_READ(RTC_MONTH);
        time.year 
= CMOS_READ(RTC_YEAR);
    } 
while (time.sec != CMOS_READ(RTC_SECONDS));
    
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
      {
        BCD_TO_BIN(time.sec);
        BCD_TO_BIN(time.min);
        BCD_TO_BIN(time.hour);
        BCD_TO_BIN(time.day);
        BCD_TO_BIN(time.mon);
        BCD_TO_BIN(time.year);
      }
    time.mon
--;
    xtime.tv_sec 
= kernel_mktime(&time);
}


//kernel/sched.c
//保存系统时间的内核变量
volatile struct timeval xtime;        

//linux/mktime.h
struct mktime {
    
int sec;  //
    int min;  //分钟
    int hour;  //小时
    int day;   //
    int mon;  //
    int year;  //
};
//kernel/mktime.c
//计算1970年1月1日00:00:00以来秒的累计值
long kernel_mktime(struct mktime * time)
{
    
long res;
    
int year;

    year 
= time->year - 70;

    res 
= YEAR*year + DAY*((year+1)/4);
    res 
+= month[time->mon];

    
if (time->mon>1 && ((year+2)%4))
        res 
-= DAY;
    res 
+= DAY*(time->day-1);
    res 
+= HOUR*time->hour;
    res 
+= MINUTE*time->min;
    res 
+= time->sec;
    
return res;
}

//linux/time.h
struct timeval {
    
long    tv_sec;        
    
long    tv_usec;    
};

(2)进程时间
该时间用来度量进程使用CPU的时间。
来看看Linux 1.0中相应的代码:

//linux/sched.h
//内核任务的结构定义
struct task_struct{
//
//依次为:用户CPU时间,系统CPU时间,子进程用户CPU时间,子进程系统CPU时间,
//进程开始运行时间
long utime,stime,cutime,cstime,start_time; 
//
}

 当度量一个进程的执行时间时,Unix系统使用三个进程时间值:
• 时钟时间。
• 用户C P U时间。
• 系统C P U时间。
要取得任一进程的时钟时间、用户时间和系统时间很容易——只要执行命令 t i m e ( 1 ),其参数是要度量其执行时间的命令,例如:
$ cd /usr/include
$ time grep _POSIX_SOURCE *
typedef 
long int __time_t;


//time.h
typedef __clock_t clock_t;
#define CLOCKS_PER_SEC  …
typedef __time_t time_t;

extern clock_t clock __P ((void));
extern time_t time __P ((time_t *__timer));

 clock函数返回当前进程的使用处理器的时间的近似值,每秒的的时钟滴答数用宏CLOCKS_PER_SEC定义。
在传统的C语言中,clock函数返回的类型为long(如上),但返回值实际上为unsigned long类型,long是在C语言加入unsigned long之前使用的。计算处理器时间总是使用无符号数算术。一些非标准实现中使用times函数,而不是clock函数,其返回的结构化值报告处理器时间的各个成员,通常以1/60秒为单位。如下:

//sys/times.h
struct tms
  {
    clock_t tms_utime;        

    clock_t tms_stime;        


    clock_t tms_cutime;        

    clock_t tms_cstime;        

  };



extern clock_t times __P ((struct tms *__buffer));

标准C中函数time返回当前的日历时间,返回值类型为time_t。

/time.h
extern char *asctime __P ((__const struct tm *__tp));


extern char *ctime __P ((__const time_t *__timer));

 这两个函数都返回时间的字符串的形式。

//time.h


extern struct tm *gmtime __P ((__const time_t *__timer));


extern struct tm *localtime __P ((__const time_t *__timer));


struct tm
{
  
int tm_sec;            
  
int tm_min;            
  
int tm_hour;            
  
int tm_mday;            
  
int tm_mon;            
  
int tm_year;            
  
int tm_wday;            
  
int tm_yday;            
  
int tm_isdst;            

#ifdef    __USE_BSD
  
long int tm_gmtoff;        
  __const 
char *tm_zone;    
#else
  
long int __tm_gmtoff;        
  __const 
char *__tm_zone;    
#endif
};

 gmtime与localtime将日历时间转换成stuct tm类型的分解形式,只不过前者转换成GMT时间,而后者转换成本地时间。

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