时间与定时器操作
三種不同精度的睡眠函數:
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 //}
總結
- 上一篇: 洛谷 P1596 [USACO10OCT
- 下一篇: [蓝桥杯][算法提高VIP]质数的后代-