时间与定时器操作
三种不同精度的睡眠函数:
1、unsigned int sleep(unsigned int seconds) 会被信号中断,返回剩余的秒数
int n=5;
do{
n=sleep(n);
}while(n>0) 确切等到5秒
2、int usleep(useconds_t usec) ; 微秒最为单位(百万分之一秒),看成无符号整数 usec[0—1000000]。
3、int nanosleep(const struct timespec *req,struct timespec *rem); 第一个表示请求要睡眠的时间,第二个表示被信号打断返回的是剩余时间
三种时间结构:
1、struct timespec{
time_t tv_sec;//秒
long tv_nsec;//纳秒 1s = 1,000,000,000 纳秒(ns)
}
2、struct timeval{
long tv_sec;//秒
long tv_usec;//微秒
}
3、time_t //秒
产生时钟信号的函数:
1、alarm产生时钟信号SIGALRM,只产生一次,需重复调用。
2、int setitimer(int which, const struct itimerval *new_value, struc itimerval * old_value);
which=ITIMER_REAL 产生SIGALRM信号,经过指定时间后,内核将发送SIGALRM信号给本进程。 会间歇性产生
which= ITIMER_VIRTUAL 产生SIGVTALRM信号,程序在用户空间执行指定时间后,内核将发送SIGVTALRM信号给本进程
which= ITIMER_PROF 进程在内核空间中执行时,时间计数会减小,通常与ITIMER_VIRTUAL共用,代表进程在用户空间与
内核空间中运行指定时间后,内核将发送SIGPROF信号给本进程。(CPU时间)
第二个参数:请求的定时时间。
struct itimerval {
struct timeval it_interval;计时器重启动的间歇值
struct timeval it_value; 计时器安装后首先启动的初始值
};
第三个参数:定时器原来关联的值。
首先打开注释部分是运行setitimer函数,发送SIGALARM信号,然后进行信号处理;然后是测试setitimer函数的第三个参数剩余时间的含义。
1 #include<unistd.h> 2 #include<sys/types.h> 3 #include<sys/stat.h> 4 #include<fcntl.h> 5 #include<stdlib.h> 6 #include<stdio.h> 7 #include<errno.h> 8 #include<string.h> 9 #include<signal.h> 10 11 #include<sys/time.h> 12 #define ERR_EXIT(m)\ 13 do\ 14 {\ 15 perror(m);\ 16 exit(EXIT_FAILURE);\ 17 }while(0) //宏要求一条语句 18 void handler(int sig); 19 int main(int argc,char*argv[]) 20 { 21 22 //if(signal(SIGALRM,handler)==SIG_ERR) 23 // ERR_EXIT("signal error"); 24 struct itimerval it; 25 struct timeval tv_interval={1,0};//间歇1秒0微秒,产生信号。表示一秒钟定时器。alarm只能精确到秒 26 struct timeval tv_value={5,0};//首先启动的间歇初始值5秒0微秒,第一次产生信号需要的时间.后面定时器1s一次 27 it.it_interval=tv_interval; 28 it.it_value=tv_value; 29 setitimer(ITIMER_REAL,&it,NULL);//过5秒第一次产生信号,然后后面每隔一秒 定时一秒发送SIGALRM信号. 30 31 //for(;;) 32 // pause(); 33 int i=0; 34 for(i=0;i<10000;i++){ 35 ; //消耗一些时间,再调用setitimer 36 } 37 struct itimerval oit; 38 setitimer(ITIMER_REAL,&it,&oit); //演示先前5秒剩余的时间,间隔时间不会变。oit会返回10000次循环之后前一个setitimer还未产生信号但还剩余的时间 39 printf("%d,%d,%d,%d\n",(int)oit.it_interval.tv_sec,(int)oit.it_interval.tv_usec,(int)oit.it_value.tv_sec,(int)oit.it_value.tv_usec); 40 return 0; 41 //或者使用gettimer(ITIMER_REAL,&it) 获取先前时钟剩余时间。 42 } 43 44 //void handler(int sig) 45 //{ 46 // printf("receive a sig=%d\n",sig);//接收到三个SIGRTMIN,只接收到一SIGINT 47 //}