第一关
任务:
获取当前时间距离 1970 年 1 月 1 日凌晨的秒数;
获取当前的本地的时间,并将时分秒分别赋值给对应的参数。
不管了,先上答案:
time_t gettimesecond (void)
{
/*************Begin***********/
return time(NULL);
/**************End************/
}
void getlocaltv (localtimestruct *ltinfo)
{
/*************Begin***********/
time_t t;
struct tm *st = localtime(&t);
ltinfo->year = st->tm_year;
ltinfo->month = st->tm_mon;
ltinfo->day = st->tm_mday;
ltinfo->hour = st->tm_hour;
ltinfo->minute = st->tm_min;
ltinfo->second = st->tm_sec;
/**************End************/
}
第二关
任务:
本关的编程任务是补全右侧代码片段 timetrans 和 getdifftimeval 中Begin至End中间的代码,具体要求如下:
在 timetrans 中,根据秒数计算对应的字符串时间、年月日时分秒和格林威治时间,并将转换得到的时间赋给相应的参数;
在 getdifftimeval 中调用函数 func,并利用 gettimeofday 计算 func 的耗时,并返回耗时(单位为微妙数)。
上答案先:
void timetrans (time_t current, char *time_str, localtimestruct *ltinfo, struct tm *tm_time)
{
/*************Begin***********/
memcpy(time_str,ctime(¤t),strlen(ctime(¤t)));
memcpy(tm_time,gmtime(¤t),sizeof(struct tm));
ltinfo->year = tm_time->tm_year+1900;
ltinfo->month = tm_time->tm_mon+1;
ltinfo->day = tm_time->tm_mday;
ltinfo->hour = tm_time->tm_hour;
ltinfo->minute = tm_time->tm_min;
ltinfo->second = tm_time->tm_sec;
/**************End************/
}
long getdifftimeval (void)
{
/*************Begin***********/
struct timeval t1;
struct timeval t2;
gettimeofday(&t1,NULL);
func();
gettimeofday(&t2,NULL);
long ans = (t2.tv_sec*1000*1000+t2.tv_sec)-(t1.tv_sec*1000*1000+t1.tv_sec);
return ans;
/**************End************/
}
第三关
任务:
本关的编程任务是补全右侧代码片段 setlocaltimer 和 loopevent 中Begin至End中间的代码,具体要求如下:
在 setlocaltimer 中,设定 3s 后第一次启动定时器;
每隔 1s 触发调用一次 loopevent;
在 loopevent 中调用 func;
loopevent 循环 5 次后,取消定时器。
注:使用 ITIMER_PROF 类型的定时器。
上答案:
void loopevent (int signo)
{
/************Begin************/
if(SIGPROF == signo)
{
func();
if(4>count)
{
count++;
}
else
{
struct itimerval new_it;
new_it.it_interval.tv_sec = 0;
new_it.it_interval.tv_usec = 0;
new_it.it_value.tv_sec = 0;
new_it.it_value.tv_usec = 0;
}
}
/*************End*************/
}
void setlocaltimer (void)
{
/************Begin************/
struct itimerval new_it;
struct itimerval old_it;
struct sigaction act;
act.sa_handler = loopevent;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF,&act,NULL);
new_it.it_interval.tv_sec = 1;
new_it.it_interval.tv_usec = 0;
new_it.it_value.tv_sec = 3;
new_it.it_value.tv_usec = 0;
setitimer(ITIMER_PROF, &new_it,&old_it);
/*************End*************/
}
说明,使用汇总:
1,获取时间秒数,如下
time_t time(time_t *t);
time_t t;
time_t t(NULL)
其实以上的几种差不多,都这样弄出来就可以显示时间秒数了。
当然返回值是:1970 年 1 月 1 日凌晨以来的秒数。
2,tm结构体获取本地时间
struct tm * localtime(const time_t * timer);//函数原型
//具体使用如下:
struct tm *current;
time_t now_second;
current = localtime(&now_second);
值得注意的是,tm里面的一些值是有范围的,需要好好注意
3,time_t时间转字符串时间
char * ctime(const time_t *timer);//函数原型
//使用:
time_t t;
char *str;
memcpy(str,ctime(&t),strlen(ctime(&t)));//这个是C语言的字符串赋值
4,tm结构体时间转字符串
char *asctime(const struct tm *tm);//函数原型
//使用:
time_t t;
struct tm *a = localtime(&t);
char *str;
memcpy(str,asctime(&t),strlen(asctime(t)));
5,time_t 时间转成格林威治时间
struct tm * gmtime(const time_t *timer); //函数原型
//使用
struct tm * tm_time;
time_t t;
memcpy(tm_time,gmtime(&t),sizeof(struct tm));
值得注意的是
结构体时间若是要转变成你想要的时间的话,
那么在返回年的时候要加1900
月的时候要加1
如下:
ltinfo->year = tm_time->tm_year+1900;
ltinfo->month = tm_time->tm_mon+1;
6,tm 结构体时间转成 time_t 时间
time_t mktime(struct tm * timeptr);//函数原型
7,获取微秒级时间
int gettimeofday(struct timeval *tv, struct timezone *tz);//函数原型
//使用:
struct timeval t1;
gettimeofday(&t1,NULL);
long thet;
thet = t1.tv_sec*1000*1000+t1.tv_sec;
//这里的thet就是返回的微秒级时间啦
// timeval结构体
struct timeval {
time_t tv_sec;/* seconds */
suseconds_t tv_usec;/* microseconds */
};
--------
在 Linux 编程中,一种很常见的定时控制是采用 sleep 来控制,这可以满足一些程序的定时需要,但是这种控制方法有一个很大的缺点,即整个应用程序在 sleep 过程中会睡眠,不会做任何事情。
如果您不希望程序偷懒,即上例中 sleep 的时候依旧希望程序做些有用的工作,那么使用定时器是通常的选择。 Linux 系统上可以使用 setitmer 来实现定时器。
8,setitimer 定时器
Linux 提供了 3 种 setitimer 间隔计时器:
ITIMER_REAL
:以系统真实的时间来计算,时间间隔到的时候会发出 SIGALRM 信号;
ITIMER_VIRTUAL
:以该进程在用户态下花费的时间来计算,产生 SIGVTALRM 信号;
ITIMER_PROF
:以该进程在用户态下和内核态下所费的时间来计算,产生 SIGPROF 信号。
接口原型:
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
参数详解如下:
which:定时器类型,即为上面提到的三种类型: ITIMER_REAL
、ITIMER_VIRTUAL
和 ITIMER_PROF
。
new_value
:指向 itimerval 变量的指针,表示设定定时器的时间属性;
old_value
:指向 itimerval 变量的指针,一般设为 NULL ;如果不为 NULL,则表示距离定时器下一次触发的时间。
返回值:调用成功时,返回 0 ;错误时,返回 -1 ,并设置相应的错误代码 errno:
EFAULT
:参数 new_value
或 old_value
是无效的指针。
EINVAL
:参数 which 不是 ITIMER_REAL
、 ITIMER_VIRT
或 ITIMER_PROF
中的一个。
取消定时器的方法,将"new_value"
的 it_value
设为 0,并调用 setitimer 即可。
使用举例:
#include <sys/time.h>
......
signal(SIGALRM, handler);
struct timeval tv_interval = {1, 0};
struct timeval tv_value = {5, 0};
struct itimerval it;
it.it_interval = tv_interval;
it.it_value = tv_value;
setitimer(ITIMER_REAL, &it, NULL);
......
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 0;
it.it_value.tv_sec = 0;
it.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &it, NULL);