日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

定时器与超时的设置

發布時間:2023/11/30 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 定时器与超时的设置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

      • 一、相關時間函數
          • 1. gettimeofday()
          • 2. time()
          • 3. clock()
      • 二、間隔定時器
          • 1. setitimerval()
          • 2. getitimerval()
          • 3. 實時定時器的使用
      • 三、為阻塞操作設置超時
          • 1. alarm()
          • 2. 給read()設置讀超時


一、相關時間函數

1. gettimeofday()

獲取日歷時間。

#include <sys/time.h>int gettimeofday(struct timeval *tv, struct timezone *tz);
  • timeval結構體
struct timeval {time_t tv_sec; // 秒suseconds_t tv_usec; // 微秒(long int) };
2. time()

返回自Epoch(格林威治標準時間1970.01.01 0:00AM)以來的秒數。

#include <time.h>time_t time(time_t *timep);

參數timep存儲返回的時間。若timep為空,則直能從函數返回值獲得。

time_t t = time(NULL);
3. clock()

計時函數。返回值為從程序啟動到調用該函數所占用CPU的時間,實際為CPU時鐘計時單元(clock tick)數。

#include <time.h>clock_t clock(void) ;

由于不同系統或編譯器對于每秒的時鐘單元數定義不同,所以直接輸出會有所不同。所以還定義了常量CLOCKS_PER_SEC,表示一秒鐘會有多少個時鐘計時單元,其定義如下:

#define CLOCKS_PER_SEC ((clock_t)1000)

CLOCKS_PER_SEC在Linux 4.15.0-32-generic系統上數值為1000000。


二、間隔定時器

1. setitimerval()

使用系統調用setitimer()來創建間隔定時器,這種定時器會在一定時間后到期,并可以在到期后每隔一段時間到期一次。

#include <sys/time.h>int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
  • which參數的可選項:

    • ITIMER_REAL
      以真實時間計時,到期產生SIGALARM信號

    • ITIMER_VIRTUAL
      以虛擬時間(用戶模式下CPU時間)計時

    • ITIMER_PROF
      創建profiling定時器以內核態與用戶態CPU時間總和計時,到期會產生SIGPROF信號

  • itimerval結構體

struct itimerval {struct timeval it_interval; // 間隔定時器的間隔時間struct timeval it_value; // 定時器到期的剩余時間 };

其中,it_value表示距離定時器到期的剩余時間,it_interval記錄定時器的周期時間(或不進行周期性定時,it_interval中兩個值同為0時表示沒有周期性定時,即一次性定時器)。若進行周期性定時,則在每次到時后會將it_interval重新存儲倒計時的間隔時間。

2. getitimerval()

獲取定時器當前狀態。

#include <sys/time.h>int getitimerval(int which, struct itimerval *curr_value );

curr_value存儲定時器當前狀態,其內容與調用setitimerval()返回的old_value內容相同。

3. 實時定時器的使用
/* 運行說明:./timer 1 800000 1 0第二個參數為倒計時的秒數,第三個參數為倒計時的微秒數,第四個參數為定時器間隔時間的秒數,第五個參數為定時器間隔時間的微秒數后四個參數可以省略,默認為 2 0 0 0 */#include <iostream> #include <string.h> #include <sys/time.h> #include <signal.h>static volatile sig_atomic_t gotAlam = 0;/* 打印時間,includeTimer表示是否為第一次打印,第一次只打印前兩個數字 */ static void displayTimes( const char *msg, bool includeTimer ) {struct itimerval itv;static struct timeval start; // 起始狀態struct timeval curr; // 當前狀態static int callNum = 0; // 當前函數被調用次數if( callNum == 0 ) {if( gettimeofday( &start, nullptr ) == -1 ) {perror( "gettimeofday" );}}/* 每20行打印一次提示信息 */if( callNum % 20 == 0 ) {printf(" Elapsed Value Interval\n");}if( gettimeofday( &curr, NULL ) == -1 ) {perror( "gettimeofday" );}printf("%-7s %6.2f", msg, curr.tv_sec - start.tv_sec + (curr.tv_usec - start.tv_usec) / 1000000.0 );/* 可以打印后兩個數字 */if( includeTimer ) {if( getitimer( ITIMER_REAL, &itv ) == -1 ) {perror( "getitimer" );}printf(" %6.2f %6.2f", itv.it_value.tv_sec + itv.it_value.tv_usec / 1000000.0, itv.it_interval.tv_sec + itv.it_interval.tv_usec / 1000000.0);}printf("\n");callNum++; }/* 信號處理函數 */ static void sigalrmHandler( int sig ) {gotAlam = 1; }int main( int argc, char **argv ) {struct itimerval itv;clock_t preClock;int maxSigs = 0; // 信號觸發最大次數int sigCnt = 0; // 信號已觸發次數struct sigaction sa;sigemptyset( &sa.sa_mask );sa.sa_flags = 0;sa.sa_handler = sigalrmHandler;if( sigaction( SIGALRM, &sa, NULL ) == -1 ) {perror( "sigaction" );}maxSigs = ( itv.it_interval.tv_sec == 0 && itv.it_interval.tv_usec == 0 ) ? 1 : 3;displayTimes( "start:", false );itv.it_value.tv_sec = (argc > 1) ? atoi( argv[1] ) : 2;itv.it_value.tv_usec = (argc > 2) ? atoi( argv[2] ) : 0;itv.it_interval.tv_sec = (argc > 3) ? atoi( argv[3] ) : 0;itv.it_interval.tv_usec = (argc > 4) ? atoi( argv[4] ) : 0;if( setitimer( ITIMER_REAL, &itv, 0 ) == -1 ) {perror( "setitimer" );}preClock = clock();while( true ) {while( ( clock() - preClock ) * 10 / CLOCKS_PER_SEC < 5 ) {/* 定時器時間到 */if( gotAlam ) {gotAlam = false;displayTimes( "ALARM:", true );sigCnt++;if( sigCnt >= maxSigs ) {printf("That's all folk\n");exit( EXIT_SUCCESS );}}}preClock = clock();displayTimes( "Main:", true );} }

三、為阻塞操作設置超時

1. alarm()

創建一次性實時定時器。

#include <unistd.h>unsigned int alarm(unsigned int seconds);

seconds表示倒計時的秒數。到期后會發送SIGALARM信號。

調用alarm(0)可以屏蔽所有現有定時器。

2. 給read()設置讀超時
#include <iostream> #include <string.h> #include <sys/time.h> #include <signal.h> #include <unistd.h> using namespace std;const int BUFFER_SIZE = 200;/* 信號處理函數 */ static void handler( int sig ) {printf("caught signal\n"); }int main( int argc, char **argv ) {struct sigaction sa;char buf[BUFFER_SIZE];ssize_t numRead;int savedErrno;sa.sa_flags = ( argc > 2 ) ? SA_RESTART : 0;sigemptyset( &sa.sa_mask );sa.sa_handler = handler;if( sigaction( SIGALRM, &sa, NULL ) == -1 ) {perror("sigaction");}/* 設置倒計時 */alarm( (argc > 1) ? atoi(argv[1]) : 10 );numRead = read( STDIN_FILENO, buf, BUFFER_SIZE - 1 );savedErrno = errno;alarm(0); // 將現有定時器屏蔽errno = savedErrno;if( numRead == -1 ) {if( errno == EINTR ) { // read系統調用被信號打斷,即收到超時信號printf("Read timed out\n");} else {perror("read");}} else { // 未超時printf("Successful read %ld bytes : %.*s", long(numRead), int(numRead), buf);}exit(EXIT_SUCCESS); }

總結

以上是生活随笔為你收集整理的定时器与超时的设置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。