linux 定時器程式設計

2021-06-23 09:01:36 字數 2895 閱讀 8199

在編寫應用程式的時候,經常需要用到定時器。根據使用情況,定時器的基本行為分為2種:single-shot timer和repeating timer 。single-shot timer 從註冊到終止只執行一次。repeating timer每次終止後自動執行。

linux 在定時程式設計有以下幾種介面:一是 setitimer ,二是posix標準的 timer_create,三是timerfd_create。

linux核心2.4版本,不支援posix標準的timer_create介面。setitimer是乙個間隔定時器,也就是定時到期後,可以自動啟動自己。原型如下:

struct itimerval ; 

struct timeval ;

int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);

int getitimer(int which, struct itimerval *curr_value);

該函式有一下三種工作模式:

timer_real 以實時時間 (real time) 遞減,在到期之後傳送 sigalrm 訊號

itimer_virtual 僅程序在使用者空間執行時遞減,在到期之後傳送 sigvtalrm 訊號

itimer_prof 程序在使用者空間執行以及核心為該程序服務時 ( 如完成乙個系統呼叫 ) 都會遞減itimer_virtual 共用時可度量該應用在核心空間和使用者空間的時間消耗情況,在到期之後傳送 sigprof 訊號

工作方式為:setitimer以new_value的值設定並啟動定時器,如果old_value的值為非空,則返回定時器的which 型別時間間隔的前乙個值。settimer從it_value開始遞減到0,然後產生乙個訊號,並以it_interval的值設定定時器。如果it_interval的值為0,定時器停止。

setitimer不支援在程序中呼叫多次以使用多個定時器。settimer要在程序中支援多次個定時器,可以用鍊錶和訊號處理方式實現。基本思想是settimer定時為基本的單位如10ms, 每個定時器為鍊錶的乙個節點,每次超時,每個定時器的定時時間遞,並檢查是否到時,是的話就執行註冊的定時處理函式。

與seitimer相比,linux2.6版本支援的posix標準timer_create函式可以在乙個程序中建立多個定時器。主要介面如下:

#include union sigval ; 

struct sigevent ;

struct itimerspec ;

int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid);

int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value,

struct itimerspec * old_value);

int timer_gettime(timer_t timerid, struct itimerspec *curr_value);

int timer_getoverrun(timer_t timerid); int timer_delete(timer_t timerid);

clockid定義的定時器型別,分為以下幾種:

clock_realtime :牆上時鐘,如果牆上時間被修改,定時時間將變化。如在8點10分設定定時1分鐘,則8點11分定時到期,在定期超時之前如果牆上時間被修改為7點0分,則要等待71分鐘才超時。

clock_monotonic:結束與開始的相對時間計算超時。

clock_process_cputime_id:以程序占用的cpu時間計算超時

clock_thread_cputime_id:以執行緒占用的cpu時間計算超時

工作方式為:timer_create建立定時器,timer_settime啟動定時器。定時器超時後,以it_interval的值設定定時器,根據建立時設定的超時通知方式處理超時。如果it_interval的值為0,定時結束,否則開始下一次定時。定時器的啟動和停止都是通過timer_settime實現。

sigev_notify的超時通知方式有:

sigev_none: 超時不以非同步的方式通知。可以呼叫timer_gettime的方式獲取定時器的狀態,但是需要注意的是用這種方式檢查定時器的超時,並不準確,在有可能在呼叫timer_gettime之前剛好超時已經過了,如果對定時精度不高如100ms級別可以使用。

sigev_signal:超時以訊號的方式通知。每次超時傳送乙個sigev_signo指定的訊號。超時時可以將sigev_value.sival_int設定為timerid的值,以此來區分多個定時器傳送相同訊號的情況。(如何實現?)

sigev_thread:超時時建立乙個執行緒的方式通知。執行緒的屬性通過sigev_notify_attributes設定。

posix的timer_create只適合在程序中使用,不適合在多執行緒下使用。為了支援在多執行緒下使用多個定時器,linux提供了基於檔案描述符的定時器介面:

#include int timerfd_create(int clockid, int flags); 

int timerfd_settime(int fd, int flags,const struct itimerspec *new_value,

struct itimerspec *old_value);

int timerfd_gettime(int fd, struct itimerspec *curr_value);

這種介面支援select函式和poll函式,並且支援fork和exec多程序語義。

linux 下定時器的實現方式分析---趙軍

Linux 定時器程式設計小解

基礎知識 全域性變數 jiffies 記錄時鐘中斷的次數,也就是system clk的節拍數 全域性變數 hz 記錄1秒鐘系統來幾個節拍,系統節拍頻率 很容易得到公式 系統執行的秒數 second jiffies hz static struct timer list my timer 定義乙個軟體...

linux程式設計之定時器

建立乙個定時器 int timer create clockid t clock id,struct sigevent evp,timer t timerid 程序可以通過呼叫timer create 建立特定的定時器,定時器是每個程序自己的,不是在fork時繼承的。clock id說明定時器是基於...

LINUX驅動程式設計 核心定時器

timer list結構體 struct timer list 1,定義乙個timer list定時器 struct timer list my timer 2,初始化定時器 1 void init timer struct timer list timer 上述init timer 函式初始化ti...