时间与定时器操作

  三种不同精度的睡眠函数:
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
",(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
",sig);//接收到三个SIGRTMIN,只接收到一SIGINT
47 //}