linux定時器總結

2021-08-27 20:53:32 字數 4660 閱讀 2504

ø  

ø  《linux系統程式設計》第「10.9 定時器」章節

要在linux中使用定時器,有如下三種方法:

定時器方式

乙個程序允許

使用的數量

通知方式

簡單的鬧鐘 - alarm

1個ø  訊號:

sigalrm

間歇定時器 - setitimer

1個ø  訊號:

sigalrm、sigvtalrm、sigprof

高階定時器 - timer_create

無限制ø  訊號:

可以自己選擇用什麼訊號

ø  啟動執行緒

就不會產生訊號,可以避免慢系統呼叫被訊號中斷的問題

有關慢系統呼叫被訊號中斷的問題可以參考我此前寫的一篇文章《訊號中斷與慢系統呼叫》:

alarm()是最簡單的定時器介面,對該函式的呼叫會在真實時間(real time)seconds秒之後將sigalrm訊號發給呼叫程序。它不能自動重啟(即定時器到後要再次定時,需要再呼叫一次alarm)。

間歇定時器setitimer系統呼叫,他可以提供比alarm()更多的控制。它能夠自動重啟。

linux 為每乙個程序提供了 3 個 setitimer 間隔計時器:

ø  itimer_real:減少實際時間,到期的時候發出 sigalrm 訊號。

ø  itimer_virtual:減少有效時間 (程序執行的時間),產生 sigvtalrm 訊號。

ø  itimer_prof:減少程序的有效時間和系統時間 (為程序排程用的時間)。這個經常和上面乙個使用用來計算系統核心時間和使用者時間。產生 sigprof 訊號。

所謂 real 時間,即我們人類自然感受的時間,英文計算機文件中也經常使用 wall-clock 這個術語。說白了就是我們通常所說的時間,比如現在是下午 5 點 10 分,那麼一分鐘的 real 時間之後就是下午 5 點 11 分。

virtual 時間是程序執行的時間,linux 是乙個多使用者多工系統,在過去的 1 分鐘內,指定程序實際在 cpu 上的執行時間往往並沒有 1 分鐘,因為其他程序會被 linux 排程執行,在那些時間內,雖然自然時間在流逝,但指定程序並沒有真正的執行。virtual 時間就是指定進**正的有效執行時間。比如 5 點 10 分開始的 1 分鐘內,程序 p1 被 linux 排程並占用 cpu 的執行時間為 30 秒,那麼 virtual 時間對於程序 p1 來講就是 30 秒。此時自然時間已經到了 5 點 11 分,但從程序 p1 的眼中看來,時間只過了 30 秒。

prof 時間比較獨特,對程序 p1 來說從 5 點 10 分開始的 1 分鐘內,雖然自己的執行時間為 30 秒,但實際上還有 10 秒鐘核心是在執行 p1 發起的系統呼叫,那麼這 10 秒鐘也被加入到 prof 時間。這種時間定義主要用於全面衡量程序的效能,因為在統計程式效能的時候,10 秒的系統呼叫時間也應該算到 p1 的頭上。這也許就是 prof 這個名字的來歷吧。

間隔定時器 setitimer 有一些重要的缺點,posix timer 對 setitimer 進行了增強,克服了 setitimer 的諸多問題:

ø  首先,乙個程序同一時刻只能有乙個 timer。假如應用需要同時維護多個 interval 不同的計時器,必須自己寫**來維護。這非常不方便。使用 posix timer,乙個程序可以建立任意多個 timer。

ø  setitmer 計時器時間到達時,只能使用訊號方式通知使用 timer 的程序,而 posix timer 可以有多種通知方式,比如訊號,或者啟動執行緒。

ø  使用 setitimer 時,通知訊號的類別不能改變:sigalarm,sigprof 等,而這些都是傳統訊號,而不是實時訊號,因此有 timer overrun 的問題;而 posix timer 則可以使用實時訊號。

備註:通過kill –l可以檢視系統支援的所有訊號列表。編號為1 ~ 31的訊號為傳統unix支援的訊號,是不可靠訊號(非實時的),編號為32 ~ 63的訊號是後來擴充的,稱做可靠訊號(實時訊號)。不可靠訊號和可靠訊號的區別在於前者不支援排隊,可能會造成訊號丟失,而後者不會。

ø  setimer 的精度是 ms,posix timer 是針對有實時要求的應用所設計的,介面支援 ns 級別的時鐘精度。

表 2. posix timer 函式

函式名

功能描述

timer_create

建立乙個新的 timer;並且指定定時器到時通知機制

timer_delete

刪除乙個 timer

timer_gettime

get the time remaining on a posix.1b interval timer

timer_settime

開始或者停止某個定時器。

timer_getoverrun

獲取丟失的定時通知個數。

使用 posix timer 的基本流程很簡單,首先建立乙個 timer。建立的時候可以指定該 timer 的一些特性,比如 clock id。clock id 即 timer 的種類,可以為下表中的任意一種:

表 3. posix timer clock id

clock id

描述

clock_realtime

settable system-wide real-time clock;

clock_monotonic

nonsettable monotonic clock

clock_process_cputime_id

per-process cpu-time clock

clock_thread_cputime_id

per-thread cpu-time clock

ø  clock_realtime 時間是系統儲存的時間,即可以由 date 命令顯示的時間,該時間可以重新設定。比如當前時間為上午 10 點 10 分,timer 打算在 10 分鐘後到時。假如 5 分鐘後,我用 date 命令修改當前時間為 10 點 10 分,那麼 timer 還會再等十分鐘到期,因此實際上 timer 等待了 15 分鐘。假如您希望無論任何人如何修改系統時間,timer 都嚴格按照 10 分鐘的週期進行觸發,那麼就可以使用clock_monotonic。

ø  clock_process_cputime_id 的含義與 setitimer 的 itimer_virtual 類似。計時器只記錄當前程序所實際花費的時間;比如還是上面的例子,假設系統非常繁忙,當前程序只能獲得 50%的 cpu 時間,為了讓進**正地執行 10 分鐘,應該到 10 點 30 分才允許 timer 到期。

ø  clock_thread_cputime_id 以執行緒為計時實體,當前程序中的某個線**正地執行了一定時間才觸發 timer。

設定到期通知方式

timer_create 的第二個引數 struct sigevent 用來設定定時器到時時的通知方式。該資料結構如下:

清單 10,結構sigevent

struct sigevent ;

其中sigev_notify 表示通知方式,有如下幾種:

表 3. posix timer 到期通知方式

通知方式

描述

sigev_none

定時器到期時不產生通知。。。

sigev_signal

定時器到期時將給程序投遞乙個訊號,sigev_signo 可以用來指定使用什麼訊號。

sigev_thread

定時器到期時將啟動新的執行緒進行需要的處理

sigev_thread_id(僅針對 linux)

定時器到期時將向指定執行緒傳送訊號。

ø  如果採用 sigev_none 方式,使用者必須呼叫timer_gettime 函式主動讀取定時器已經走過的時間。類似輪詢。

ø  如果採用 sigev_signal 方式,使用者可以選擇使用什麼訊號,用 sigev_signo 表示訊號值,比如 sig_alarm。

ø如果使用 sigev_thread 方式,則需要設定 sigev_notify_function,當 timer 到期時,將使用該函式作為入口啟動乙個執行緒來處理訊號;sigev_value 儲存了傳入 sigev_notify_function 的引數。sigev_notify_attributes 如果非空,則應該是乙個指向 pthread_attr_t 的指標,用來設定執行緒的屬性(比如 stack 大小,detach 狀態等)。

ø  sigev_thread_id 通常和 sigev_signal 聯合使用,這樣當 timer 到期時,系統會向由 sigev_notify_thread_id 指定的執行緒傳送訊號,否則可能程序中的任意執行緒都可能收到該訊號。這個選項是 linux 對 posix 標準的擴充套件,目前主要是 glibc 在實現 sigev_thread 的時候使用到,應用程式很少會需要用到這種模式。

linux核心定時器

度量時間差 時鐘中斷由系統的定時硬體以週期性的時間間隔產生,這個間隔 頻率 由核心根據hz來確定,hz是乙個與體系結構無關的常數,可配置 50 1200 在x86平台,預設值為1000.每秒鐘產生1000次時鐘中斷 每當時鐘中斷發生時,全域性變數jiffies就加1,因此其記錄了自linux啟動後時...

Linux 核心定時器

include include include include struct timer list my timer void func unsigned long data printk time out n data ld,pid ld n data,current pid mod timer ...

linux 定時器程式設計

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