头歌实验6:Linux时间编程

第一关

任务:
获取当前时间距离 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(&current),strlen(ctime(&current)));
    memcpy(tm_time,gmtime(&current),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_REALITIMER_VIRTUALITIMER_PROF
new_value:指向 itimerval 变量的指针,表示设定定时器的时间属性;
old_value:指向 itimerval 变量的指针,一般设为 NULL ;如果不为 NULL,则表示距离定时器下一次触发的时间。
返回值:调用成功时,返回 0 ;错误时,返回 -1 ,并设置相应的错误代码 errno:

EFAULT:参数 new_valueold_value 是无效的指针。

EINVAL:参数 which 不是 ITIMER_REALITIMER_VIRTITIMER_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);
  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泉绮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值