Ⅰ linux 下 select 函数 延时的问题
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int rc = 0;
struct timeval tv;
while (true)
{
tv.tv_sec = 5;
tv.tv_usec = 0;
rc = select(0, NULL, NULL, NULL, &tv);
printf("select = %d\n", rc);
}
return 0;
}
Ⅱ 怎样在Linux下实现精确定时器
linux下使用select实现精确定时器
在编写程序时,我们经常回用到定时器。本文讲述如何使用select实现超级时钟。使用select函数,我们能实现微妙级别精度的定时器。同时,select函数也是我们在编写非阻塞程序时经常用到的一个函数。
首先看看select函数原型如下:
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
参数说明:
slect的第一个参数nfds为fdset集合中最大描述符值加1,fdset是一个位数组,其大小限制为__FD_SETSIZE(1024),位数组的每一位代表其对应的描述符是否需要被检查。
select的第二三四个参数表示需要关注读、写、错误事件的文件描述符位数组,这些参数既是输入参数也是输出参数,可能会被内核修改用于标示哪些描述符上发生了关注的事件。所以每次调用select前都需重新初始化fdset。
timeout参数为超时时间,该结构会被内核修改,其值为超时剩余的时间。
利用select实现定时器,需要利用其timeout参数,注意到:
1)select函数使用了一个结构体timeval作为其参数。
2)select函数会更新timeval的值,timeval保持的值为剩余时间。
如果我们指定了参数timeval的值,而将其他参数都置为0或者NULL,那么在时间耗尽后,select函数便返回,基于这一点,我们可以利用select实现精确定时。
timeval的结构如下:
struct timeval{
long tv_sec;/*secons*
long tv_usec;/*microseconds*/
}
我们可以看出其精确到microseconds也即微妙。
一、秒级定时器
void seconds_sleep(unsigned seconds){
struct timeval tv;
tv.tv_sec=seconds;
tv.tv_usec=0;
int err;
do{
err=select(0,NULL,NULL,NULL,&tv);
}while(err<0 && errno==EINTR);
}
二、毫秒级别定时器
void milliseconds_sleep(unsigned long mSec){
struct timeval tv;
tv.tv_sec=mSec/1000;
tv.tv_usec=(mSec%1000)*1000;
int err;
do{
err=select(0,NULL,NULL,NULL,&tv);
}while(err<0 && errno==EINTR);
}
三、微妙级别定时器
void microseconds_sleep(unsigned long uSec){
struct timeval tv;
tv.tv_sec=uSec/1000000;
tv.tv_usec=uSec%1000000;
int err;
do{
err=select(0,NULL,NULL,NULL,&tv);
}while(err<0 && errno==EINTR);
}
现在我们来编写几行代码看看定时效果吧。
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
int main()
{
int i;
for(i=0;i<5;++i){
printf("%d\n",i);
//seconds_sleep(1);
//milliseconds_sleep(1500);
microseconds_sleep(1900000);
}
}
注:timeval结构体中虽然指定了一个微妙级别的分辨率,但内核支持的分别率往往没有这么高,很多unix内核将超时值向上舍入成10ms的倍数。此外,加上内核调度延时现象,即定时器时间到后,内核还需要花一定时间调度相应进程的运行。因此,定时器的精度,最终还是由内核支持的分别率决定。
Ⅲ linux获取时间戳linux获取时间戳
linux获取时间戳的函数有哪些?
1.获取当前时间
a.获取系统当前的秒数和毫秒数
structtimevaltv;
gettimeofday(tv,NULL);
b.获取系统当前时间的秒数
time_tnow=time(NULL)
2.获取日历时间
a.gmtime函数返回一个structtm
time_tnow=time(NULL);
structtmt1=*gmtime(now);//获取UTC时间
structtmt2=*localtime(now);//获取local时间
time_tseconds=static_casttime_t>(tv.tv_sec);
b.gmtime_r函数直接赋值给传入的第二个参数
structtmtm_time;
gettime_r(seconds,tm_time);
localtime_r(seconds,tm_time);
Ⅳ linux下,记录响应时间的脚本,精确到毫秒ms
gettimeofday(取得目前的时间)
相关函数
time,ctime,ftime,settimeofday
表头文件
#include <sys/time.h>
#include <unistd.h>
定义函数
int gettimeofday ( struct timeval * tv , struct timezone * tz )
函数说明
gettimeofday()会把目前的时间有tv所指的结构返回,当地时区的信息则放到tz所指的结构中。
timeval结构定义为:
struct timeval{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
timezone 结构定义为:
struct timezone{
int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};
上述两个结构都定义在/usr/include/sys/time.h。tz_dsttime 所代表的状态如下
DST_NONE /*不使用*/
DST_USA /*美国*/
DST_AUST /*澳洲*/
DST_WET /*西欧*/
DST_MET /*中欧*/
DST_EET /*东欧*/
DST_CAN /*加拿大*/
DST_GB /*大不列颠*/
DST_RUM /*罗马尼亚*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以后)*/
返回值
成功则返回0,失败返回-1,错误代码存于errno。附加说明EFAULT指针tv和tz所指的内存空间超出存取权限。
范例
#include<sys/time.h>
#include<unistd.h>
main(){
struct timeval tv;
struct timezone tz;
gettimeofday (&tv , &tz);
printf(“tv_sec; %d\n”, tv,.tv_sec) ;
printf(“tv_usec; %d\n”,tv.tv_usec);
printf(“tz_minuteswest; %d\n”, tz.tz_minuteswest);
printf(“tz_dsttime, %d\n”,tz.tz_dsttime);
}
执行
tv_sec: 974857339
tv_usec:136996
tz_minuteswest:-540
tz_dsttime:0
Ⅳ Linux下C语言获得系统时间的方法
没有完整程序, 不过能提供一点资料
int gettimeofday(struct timeval * tv,struct timezone *tz);
这个函数可以获取当前时间, 貌似只要第一个结构体就行了
struct timeval
{
time_t tv_sec; //秒 [long int]
suseconds_t tv_usec; //微秒 [long int], (10E-6 second)
};
struct timeval
{
long tv_sec;
long tv_usec;
};
然后取微秒的前三位就是小数了, 之后把秒 tv_sec 转化为 tm 格式, 参数用秒的指针就行
struct tm * gmtime(const time_t * t);
//转换成格林威治时间。有时称为GMT或UTC。
struct tm * localtime(const time_t *t);
//转换成本地时间。它可以透过修改TZ环境变数来在一台机器中,不同使用者表示不同时间.
下面是tm的部分参数
int tm_sec; //tm_sec表“秒”数,在[0,61]之间,多出来的两秒是用来处理跳秒问题用的。/* Seconds: 0-59 (K&R says 0-61?) */
int tm_min; //tm_min表“分”数,在[0,59]之间。
int tm_hour; //tm_hour表“时”数,在[0,23]之间。
int tm_mday; //tm_mday表“本月第几日”,在[1,31]之间。
int tm_mon; //tm_mon表“本年第几月”,在[0,11]之间。
int tm_year; //tm_year要加1900表示那一年。 /* /* 年份,其值从1900开始 */*/
int tm_wday; //tm_wday表“本周第几日”,在[0,6]之间。 /* Days since Sunday (0-6) */ /*其中0代表星期天,1代表星期一,以此类推 */
int tm_yday; //tm_yday表“本年第几日”,在[0,365]之间,闰年有366日。 /*其中0代表1月1日,1代表1月2日,以此类推 */*/
int tm_isdst; //tm_isdst表是否为“日光节约时间”
------------------------------华丽丽的分割线--------------------------------------------------
由于很长时间没编程了, 也没有Linux环境, 我就简单写几行代码, 仅作参考
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include<unistd.h>
//这四个不一定够用了
struct timeval tv;
struct timezone tz;
struct tm * p_tm;
//变量没有初始化习惯不好,不要学
gettimeofday(&tv, &tz);
p_tm = gmtime( (const time_t *)&tv.tv_sec );
字符串的组装尤其格式问题自己解决吧
年 p_tm->tm_year+ 1900
月 p_tm->tm_mon+ 1
日 p_tm->tm_mday
时 p_tm->tm_hour+ 1
分 p_tm->tm_min+ 1
秒 p_tm->tm_sec+ 1
小数点后面的部分,注意不够三位还是前面填充0 tv.tv_sec/1000