Linux系统编程6之时间

1.基本介绍:

对于Linux系统来说:其中的绝对时间表示成新纪元至今经过的秒数,新纪元定义为1970年1月1日00:00:00.下面将介绍有关Linux系统中的时间函数。

2.成员介绍

1).微秒级精确:

#include <sys/time.h>

struct timeval {
  time_t  tv_sec;/*seconds*/
  suseconds_t tv_usec; /* 微秒*/
};

2).原始表示:

 Linux时间类中,最简单的数据结构是time_t,在头文件<time.h>中。,其返回的新纪元到至今经过的秒数。如下函数调用获得当前时间。

#include <time.h>

time_t timer=time(NULL);

3).纳秒级别的精度:
因为在一些情况下,毫秒级别的精度还是不够精确。timespec结构体将时间提升到纳秒级别。

#include <time.h>

struct timespec{
  time_t tv_sec;/*秒*/
  long   tv_nsec; /*纳秒*/

};

LINUX系统中,大多数的时间相关的函数都与纳秒有关,所以结构体timeval和timespec两个用的最多。

3.对时间类进行分解

Linux系统中一些函数或者操作需要将时间和字符串进行相互转换,所以有了可以将时间进行分解的结构体 struct tm;

struct tm{
   int tm_sec;//秒 0~59
   int tm_min;//分钟 0~59
   int tm_hour;//小时 0~23
   int tm_mday;//天 0~31
   int tm_mon;//月 0~11
   int tm_year;//年 从1900年以来的年数 一般提取出来+1900
   int tm_wday;//以周日以来的天数 0~6
   int tm_yday;//从1月1日以来的日期,0~365
   int tm_isdet;
   long tm_gmtoff;
   const char* tm_zone;
};

进程时间类和时间源精度相关的知识不做介绍,因为用的很少。

4.获得当前的时间:

除了调用 time_t time(time_t* ) 函数 还有其他高级调用。

#include <sys/time.h>

 int gettimeofday(struct timeval* tv,struct timezone* tz);
该函数调用时会将时间存入tv存入的结构体中,结构体timezone已经废弃,所以传NULL即可。
是失败时返回-1.

与clock相关的函数不过多介绍。

5.设置当前时间:

对于应用程序,有时也需要将当前时间日期设置为一个定值。

#define _SVID_SOURCE
#include <time.h>

int stime(time_t* t);
函数调用时,会设置系统函数时间为t所指向的值并且返回0,调用失败时返回-1,但调用需要define后面的宏
一般情况下只有root用户才有该权限。
#include <sys/time.h>

int settimeofday(const struct timeval* tv,const struct timezone* tz);

成功调用后,会将系统时间设置为tv提供的值,并且返回零。tz参数最好给其提供NULL,调用失败返回-1.


struct timeval tv={.tv_sec=0,.tv_usec=0};
int ret=settimeofday(&tv,NULL);

6.时间类的转换:
gmtime()函数会将time_t转换为tm结构体,通过UTC时区格式表示

#include <time.h>

struct tm* gmtime (const time_t * timep);
struct tm* gmtime_r (const time_t* timep,struct tm* result);
调用失败,返回NULL
函数一是返回静态分配的结构体指针,所以线程不安全,
函数二对于线程是安全的,其操作结果在第二个参数上。

localtime和gmtime类似 但是是通过用户时区显示。

#include <time.h>

struct tm* localtime (const time_t * timep);
struct tm* localtime_r (const time_t* timep,struct tm* result);
调用失败,返回NULL
函数一是返回静态分配的结构体指针,所以线程不安全,
函数二对于线程是安全的,其操作在第二个参数上。

difftime会返回两个time_t值的秒数差,并且强转为double.

#include <time.h>

double difftime(time_t time1,time_t time2);


(double)(time1-time2)  是前减后

7.睡眠和等待;

LINUX系统中的睡眠函数有秒,微秒.

#include <unistd.h>

以秒睡眠

unsigned int sleep(unsigned int seconds);

以微秒进行睡眠

void usleep(unsigned long usec);

unsigned int usec=200;
  usleep(usec);


对于纳秒时间来睡眠用的比较少,所以不过多介绍了。

8.定时器:

一般来说,Linux定时器一般与发送信号绑定在一起,下面介绍相关用的比较多的两个函数。

1).alarm函数

#include <unistd.h>
#include <signal.h>

int alarm(int seconds);

发起调用后,此函数会在seconds后将SIGALRM信号发送给进程,
若先前信号未处理,调用就取消该信号,用新的信号覆盖它,
一般成功发送处信号,就需要为信号注册一个信号处理函数,
可以用struct sigaction结构体和sigaction()函数进行封装,或者调用signal()函数

void alarm_handler(int sig){

printf("five second passed!\n");

}

void func(){
 sigal(SIGALRM,alarm_handler);
 alarm(5);
}

注意一次进程/线程进行只能调用一次alarm()函数,alarm()函数不能重启

2).setitimer()函数:

#include <sys/time.h>

int setitimer(int which,const struct itimerval* value,struct itimerval* ovalue);

和alarm类似,但是此函数能重启,其有三种工作方式,作者只说明 “以测量真实时间”的工作方式。
以测量真实时间,第一个参数要指定 ITIMER_REAL。

itimerval结构体指定用户设置定时器过期或终止的时限,如果设定了值,则在过期后重启定时器。

struct itimerval{

  struct timeval it_interval; //发送完信号后,经过it_interval后重启函数调用。
  struct timeval it_value;   // 函数调用后,经过it_value时间发送SIGALRM信号
};

这就说明发送SIGALRM信号的间隔为  it_interval+it_value,若定时器失败且it_interval=0;,
则不会重启定时器,it_value被设置为0,也不会发送信号。
,in_interval=0且it_value!=0,就是周期性的alarm()函数

若函数的第三个参数不为NULL,则储存定时器的前一个值。调用成功,函数返回零

#include <signal.h>
#include <sys/time.h>



void alarm_handler(int sig){

printf(" passed over!\n");

}

void foo(void){
   struct itimerval dealy;
int ret=0;
 signal(SIGALRM,alarm_handler);

dealy.it_value.tv_sec=5;
dealy.it_value.tv_usec=0;
dealy.it_interval.tv_sec=1;
dealy.it_interval.tv_usec=0;
ret=setitimer(ITIMER_REAL,&dealy,NULL);
if(ret){
perror("error");
return ;
}
pause();
}

但要注意alarm()函数和setitimer()函数不要混用。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值