A. linux实时时间 xtime怎么获取并使用
RTC时间操作:
1.rtc时间是由rtc硬件控制的,所以在linux中想要修改和获取rtc时间就只能通过驱动的接口来获取和修改。
intrtc_test(void)
{
structrtc_timertc;
intfd=-1;
intret=-1;
fd=open("/dev/rtc0",O_RDWR);
if(fd<0){
return-1;
}
ret=ioctl(fd,RTC_RD_TIME,&rtc);
if(ret<0){
return-1;
}
printf(" CurrentRTCdata/timeis%d-%d-%d,%02d:%02d:%02d. ",rtc.tm_mday,rtc.tm_mon+1,
rtc.tm_year+1900,rtc.tm_hour,rtc.tm_min,rtc.tm_sec);
ret=ioctl(fd,RTC_SET_TIME,&rtc);
if(ret<0){
return-1;
}
return0;
}
2.除了上面这种方式操作rtc时间以外,linux中也有一个命令可以简化rtc时间操作,hwclock,比如,可以通过system("hwclock-w");系统调用来把xtime设置到rtc硬件。
墙上时间(realtime、xtime):
linux系统中主要使用的就是xtime,它是系统运行的基础,很多程序都是依赖于xtime来运行的,接下来将介绍将如何操作xtime。
1.获取、设置微秒级别的时间:
#include
#include
structtimeval
{
inttv_sec;
inttv_usec;
};
intgettimeofday(structtimeval*tv,structtimezone*tz);
intsettimeofday(conststructtimeval*tv,conststructtimezone*gz);
功能描述:
gettimeofday()获取当前时间,有tv指向的结构体返回。
settimeofday()把当前时间设成由tv指向的结构体数据。当前地区信息则设成tz指向的结构体数据。
2.获取秒级别的时间
typedeflongtime_t;
time_ttime(time_t*t);
如果t是non-null,它将会把时间值填入t中
3.内核2.6版本后新增的clockapi接口
获取纳秒级别的时间
structtimespec{
time_ttv_sec;/*秒s*/
longtv_nsec;/*纳秒ns*/
};
intclock_getres(clockid_tclk_id,structtimespec*res);
intclock_gettime(clockid_tclk_id,structtimespec*tp);
intclock_settime(clockid_tclk_id、conststructtimespec*tp);
编译连接时采用-lrt才能编译通过。
clk_id可选参数:
CLOCK_REALTIME
系统全局的实时时钟.设置此时钟需要合适的权限.
CLOCK_MONOTONIC
只能被读取,无法被设置,表示monotonic时间起点.
CLOCK_PROCESS_CPUTIME_ID
从cpu每进程的高分辨率计时器.
CLOCK_THREAD_CPUTIME_ID
线程的特定cpu时间时钟.
系统启动时,会首先从rtc中读取rtc时间,并设置给xtime,而当ntp对系统时间进行更新时,首先设置xtime,然后调用hwclock设置到rtc硬件中。xtime根据需要的精度,可以通过上面几个接口来选择使用。
B. linux环境中的sleep和setitimer计时器会不会冲突
如果你是担心多次alarm调用问题,那就不必担心。
APUE上在介绍alarm函数时专门写了专一个sleep事例函数。
现在所属用的sleep函数是做了这方面的考虑的。
“如果调用者已设置了闹钟,则它被s l e e p 1函数中的第一次a l a r m调用擦去。
可用下列方法更正这一点:检查第一次调用a l a r m的返回值,如其小于本次调用a l a r m的参数值,则只应等到该前次设置的闹钟时间超时。如果前次设置闹钟时间的超时时刻后于本次设
置值,则在s l e e p 1函数返回之前,再次设置闹钟时间,使其在预定时间再发生超时。”
C. Linux系统编程的内容简介
在某些时刻,几乎所有的程序员都要与其程序所处操作系统中的系统调用和程序库打交道。本书主要讨论如何编写Linux系统软件——代码位于底层,并且直接跟内核及核心系统程序库对话。《Linux系统编程》描述了使用标准接口包括使用Linux独有的高级接口时,在功能和性能之间如何进行权衡取舍的策略。
本书主题包括:
· 读写文件以及其他文件I/O操作,包括Linux内核如何实现和管理文件I/O,内存映射与优化技术
· 进程管理的系统调用,包括实时进程
· 文件与目录——创建、移动、复制、删除和管理
· 内存管理——内存分配接口,管理内存,以及优化内存访问
· 信号及其在Unix系统中的角色,以及基本和高级信号接口
· 时间、休眠和时钟管理,从基础开始讲述,并且涵盖POSIX时钟和高精度计时器
拥有《Linux系统编程》,你将从理论和应用的角度深入了解Linux,可以最大限度地利用系统的潜能。
D. Linux编程itimerval计时器结构体问题
楼主的程序没有用 signal 注册 SIGPROC 对应函数,在 for 循环的时候可能已经发生了多次中断和重置计时器。至于比1秒大,手册中有解释 Timers will never expire before the requested time, but may expire some (short) time afterward, which depends on the system timer resolution and on the system load; see time(7).
要在1秒间隔调用一个函数,需要加上 signal,比如
#include<signal.h>
#include<sys/time.h>
#include<stdio.h>
#include<time.h>
staticstructitimervala;
voidtimeover(intevent)
{
structitimervalb;
printf("timeoverat%ld ",time(NULL));
getitimer(ITIMER_PROF,&b);
printf("sec=%ld,usec=%ld ",b.it_value.tv_sec,b.it_value.tv_usec);
}
intmain()
{
signal(SIGPROF,timeover);
printf("beginat%ld ",time(NULL));
a.it_interval.tv_sec=1;
a.it_interval.tv_usec=0;
a.it_value.tv_sec=1;
a.it_value.tv_usec=0;
setitimer(ITIMER_PROF,&a,NULL);
while(1);
return0;
}
E. c语言中怎么设置计时器
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
clock_t start = clock();
//do some process here
clock_t end = (clock() - start)/CLOCKS_PER_SEC;
cout<<"time comsumption is "<<end<<endl;
}
(5)linux系统编程计时器扩展阅读
使用linux的系统设置计时器
#include <sys/time.h>
int main()
{
timeval starttime,endtime;
gettimeofday(&starttime,0);
//do some process here
gettimeofday(&endtime,0);
double timeuse = 1000000*(endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - startime.tv_usec;
timeuse /=1000;//除以1000则进行毫秒计时,如果除以1000000则进行秒级别计时,如果除以1则进行微妙级别计时
}
timeval的结构如下:
strut timeval
{
long tv_sec; /* 秒数 */
long tv_usec; /* 微秒数 */
};
F. linux手册翻译——timerfd_create(2)
timerfd_create, timerfd_settime, timerfd_gettime - timers that notify via file descriptors
这些系统调用创建并操作一个计时器,计时器通过文件描述符来通知计时到期,这样就可以通过 select(2)、poll(2) 和 epoll(7) 监视文件描述符从而监听计时器。
这三个系统调用的使用类似于 timer_create(2)、timer_settime(2) 和 timer_gettime(2) 。 (没有与timer_getoverrun(2) 类似的系统调用,因为该功能由 read(2) 提供,如下所述。)
int timerfd_create(int clockid, int flags);
timerfd_create() 创建一个新的计时器对象,并返回引用该计时器的文件描述符。 clockid 参数指定使用那种类型的时钟(clock)来实现计时器(timer),并且必须是以下之一:
有关上述时钟的更多详细信息,请参阅clock_getres(2)。
可以使用clock_gettime(2) 获取每个时钟的当前值。
从 Linux 2.6.27 开始,可以在标志中对以下值进行厅局轿按位 OR 运算以更改 timerfd_create() 的行为:
在 2.6.26 及包括 2.6.26 的 Linux 版本中,标志必须指定为零。
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
timerfd_settime() arms (starts) or disarms (stops) the timer referred to by the file descriptor fd.
new_value 参数指定计时器的初始到期时间和到期间隔(换句话说,计时器开始执行后,将会在到达初始到期时间时报告一次,此后每过一个到期间隔就会报告一次)。 用于此参数的 itimerspec 结构包含两个字段,每个字段又是一个 timespec 类型的结构:
new_value.it_value 指定计时器的初始到期时间,以秒和纳秒为单位。 将 new_value.it_value 的任一字段设置为非零值,即可启动计时器。 将 new_value.it_value 的两个字段都设置为零会解除定时器。
将 new_value.it_interval 的一个或两个字段设置为非零值指定初始到期后重复计时器到期的时间段(以秒和纳秒为单位)。 如果 new_value.it_interval 的两个字段都为零,则计时器仅在 new_value.it_value 指定的时间到期一次。
如果将 new_value 设置为(10S,2S),即表示,计时器启动后,将会在扮肆10S后报告一次,然后每隔2S报告一次;
如果将 new_value 设置为(10S,0S),即表示,计时器启动后,将会在10S后报告一次,然后就不再报告了;
如果将 new_value 修改为(0S,0S),即表示,停止计时。腊枝
默认情况下, new_value 中指定的初始到期时间是相对于调用时计时器时钟上的当前时间的(即,new_value.it_value 是相对于 clockid 指定的时钟的当前值设置的)。 可以通过 flags 参数指定使用绝对时间。
flags 参数是一个位掩码,可以包含以下值:
如果 old_value 参数不为 NULL,则它指向的 itimerspec 结构用于返回调用时当前计时器的设置; 请参阅下面的 timerfd_gettime() 说明。
int timerfd_gettime(int fd, struct itimerspec *curr_value);
timerfd_gettime() 在 curr_value 中返回一个 itimerspec 结构,该结构包含文件描述符 fd 所引用的计时器的当前设置。
it_value 字段返回计时器下一次到期之前的时间量。 如果此结构的两个字段都为零,则定时器当前已解除。 无论在设置计时器时是否指定了 TFD_TIMER_ABSTIME 标志,该字段始终包含一个相对值。
it_interval 字段返回定时器的间隔。 如果此结构的两个字段都为零,则计时器设置为仅在 curr_value.it_value 指定的时间到期一次。
timerfd_create() 返回的文件描述符支持以下附加操作:
在 fork(2) 之后,子进程继承了 timerfd_create() 创建的文件描述符的副本。 文件描述符引用与父级中相应文件描述符相同的底层计时器对象,子级中的 read(2) 将返回有关计时器到期的信息。
A file descriptor created by timerfd_create() is preserved across execve(2), and continues to generate timer expirations if the timer was armed.
成功时, timerfd_create() 返回一个新的文件描述符。 出错时,返回 -1 并设置 errno 以指示错误。
timerfd_settime() 和 timerfd_gettime() 成功返回 0; 出错时返回 -1,并设置 errno 以指示错误。
timerfd_create() can fail with the following errors:
timerfd_settime() and timerfd_gettime() can fail with the following errors:
timerfd_settime() can also fail with the following errors:
These system calls are available on Linux since kernel 2.6.25.
Library support is provided by glibc since version 2.8.
These system calls are Linux-specific.
假设在使用 timerfd_create() 创建的 CLOCK_REALTIME 或 CLOCK_REALTIME_ALARM 计时器时,发生以下场景:
在这种情况下,会发生以下情况:
目前,timerfd_create() 支持的时钟 ID 类型少于 timer_create(2)。
以下程序创建一个 基于实时时钟的绝对时间 的计时器,然后监控其进度。 该程序最多接受三个命令行参数。 第一个参数指定计时器初始到期的秒数。 第二个参数指定计时器的间隔,以秒为单位。 第三个参数指定程序在终止前应允许计时器到期的次数。 第二个和第三个命令行参数是可选的。
以下 shell 会话演示了该程序的使用:
G. linux定时任务
linux定时任务使用crontab命令
crontab命令说明
crontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
语法
crontab(选项)(参数)
选项
-e:编辑该用户的计时器设置;
-l:列出该用户的计时器设置;
-r:删除该用户的计时器设置;
-u<用户名称>:指定要设定计时器的用户名称。
参数
crontab文件:指定包含待执行任务的crontab文件。
知识扩展
Linux下的任务调度分为两类:系统任务调度和用户任务调度。
系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。在/etc目录下有一个crontab文件,这个就是系统任务调度的配置文件。
/etc/crontab文件包括下面几行:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""HOME=/
# run-parts
51 * * * * root run-parts /etc/cron.hourly
24 7 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
前四行是用来配置crond任务运行的环境变量,第一行SHELL变量指定了系统要使用哪个shell,这里是bash,第二行PATH变量指定了系统执行命令的路径,第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户,如果MAILTO变量的值为空,则表示不发送任务执行信息给用户,第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。
用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab文件都被保存在/var/spool/cron目录中。其文件名与用户名一致,使用者权限文件如下:
/etc/cron.deny 该文件中所列用户不允许使用crontab命令
/etc/cron.allow 该文件中所列用户允许使用crontab命令
/var/spool/cron/ 所有用户crontab文件存放的目录,以用户名命名
crontab文件的含义:用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下:
minute hour day month week command 顺序:分 时 日 月 周
其中:
minute: 表示分钟,可以是从0到59之间的任何整数。
hour:表示小时,可以是从0到23之间的任何整数。
day:表示日期,可以是从1到31之间的任何整数。
month:表示月份,可以是从1到12之间的任何整数。
week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。
在以上各个字段中,还可以使用以下特殊字符:
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。
crond服务
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
查看crontab服务状态:
service crond status
手动启动crontab服务:
service crond start
查看crontab服务是否已设置为开机启动,执行命令:
ntsysv
加入开机自动启动:
chkconfig –level 35 crond on
H. linux使用crontab实现PHP执行计划定时任务
首先说说cron,它是一个linux下的定时执行工具。根用户以外的用户可以使用
crontab
工具来配置
cron
任务。所有用户定义的
crontab
都被保存在/var/spool/cron
目录中,并使用创建它们的用户身份来执行。要以某用户身份创建一个
crontab
项目,登录为该用户,然后键入
crontab
-e
命令来编辑该用户的
crontab。该文件使用的格式和
/etc/crontab
相同。当对
crontab
所做的改变被保存后,该
crontab
文件就会根据该用户名被保存,并写入文件
/var/spool/cron/username
中。cron
守护进程每分钟都检查
/etc/crontab
文件、etc/cron.d/
目录、以及
/var/spool/cron
目录中的改变。如果发现了改变,它们就会被载入内存。这样,当某个
crontab
文件改变后就不必重新启动守护进程了。
安装crontab:
yum
install
crontabs
说明:
/sbin/service
crond
start
//启动服务
/sbin/service
crond
stop
//关闭服务
/sbin/service
crond
restart
//重启服务
/sbin/service
crond
reload
//重新载入配置
查看crontab服务状态:service
crond
status
手动启动crontab服务:service
crond
start
查看crontab服务是否已设置为开机启动,执行命令:ntsysv
加入开机自动启动:
chkconfig
–level
35
crond
on
crontab命令:
功能说明:设置计时器。
语法:crontab
[-u
<用户名称>][配置文件]
或
crontab
[-u
<用户名称>][-elr]
补充说明:cron是一个常驻服务,它提供计时器的功能,让用户在特定的时间得以执行预设的指令或程序。只要用户会编辑计时器的配置文件,就可以使
用计时器的功能。其配置文件格式如下:
Minute
Hour
Day
Month
DayOFWeek
Command
参数:
-e
编辑该用户的计时器设置。
-l
列出该用户的计时器设置。
-r
删除该用户的计时器设置。
-u<用户名称>
指定要设定计时器的用户名称。
crontab
格式:
基本格式
:
分钟
小时
日
月
星期
命令
*
*
*
*
*
*
第1列表示分钟1~59
每分钟用*或者
*/1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列
表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令
记住几个特殊符号的含义:
“*”代表取值范围内的数字,
“/”代表”每”,
“-”代表从某个数字到某个数字,
“,”分开几个离散的数字
#
Use
the
hash
sign
to
prefix
a
comment
#
+—————-
minute
(0
–
59)
#
|
+————-
hour
(0
–
23)
#
|
|
+———-
day
of
month
(1
–
31)
#
|
|
|
+——-
month
(1
–
12)
#
|
|
|
|
+—-
day
of
week
(0
–
7)
(Sunday=0
or
7)
#
|
|
|
|
|
#
*
*
*
*
*
command
to
be
executed
crontab几个例子如下:
(1)第一个例子。
30
21
*
*
*
/etc/init.d/nginx
restart
每晚的21:30重启
nginx。
(2)第二个例子,也就是本教程测试的例子
*
*
*
*
*
/usr/bin/php
-f
/root/test.php
>>
test.log
每一分钟执行/root/test.php文件,将结果输出到test.log中。
完成了上面基础工作后,就来看看怎么使用crontab定时执行PHP脚本:
(1)我在/root下新建test.php文件,内容如下:
复制代码
代码如下:
<?php
#!/usr/bin/php
-q
echo
date('Y-m-d
H:i:s')."from
http://www.phpddt.com
";
?>
说明:你可以用whereis
php查找php执行文件位置。
(2)然后crontab
-e编写如下shell:
复制代码
代码如下:
*
*
*
*
*
/usr/bin/php
-f
/root/test.php
>>
test.log
说明:test.php必须为可执行文件:chmod
+x
test.php
测试结果很正常,截图如下:
当然你可以用使用crontab
-e继续添加任务,在/var/spool/cron下你可以看到一个root文件。
windows下直接用windows计划任务,通过bat打开网页就可以了。不像linux这么复制。