定時器 sigevent結構體詳解

2021-10-09 09:37:55 字數 3517 閱讀 2828

最強大的定時器介面來自posix時鐘系列,其建立、初始化以及刪除乙個定時器的行動被分為三個不同的函式:timer_create()(建立定時器)、timer_settime()(初始化定時器)以及timer_delete(銷毀它)。

建立乙個定時器:

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

程序可以通過呼叫timer_create()建立特定的定時器,定時器是每個程序自己的,不是在fork時繼承的。clock_id說明定時器是基於哪個時鐘的,*timerid裝載的是被建立的定時器的id。該函式建立了定時器,並將他的id 放入timerid指向的位置中。引數evp指定了定時器到期要產生的非同步通知。如果evp為null,那麼定時器到期會產生預設的訊號,對 clock_realtimer來說,預設訊號就是sigalrm。如果要產生除預設訊號之外的其它訊號,程式必須將 evp->sigev_signo設定為期望的信號碼。struct sigevent 結構中的成員evp->sigev_notify說明了定時器到期時應該採取的行動。通常,這個成員的值為sigev_signal,這個值說明在定時器到期時,會產生乙個訊號。程式可以將成員evp->sigev_notify設為sigev_none來防止定時器到期時產生訊號。 

如果幾個定時器產生了同乙個訊號,處理程式可以用 evp->sigev_value來區分是哪個定時器產生了訊號。要實現這種功能,程式必須在為訊號安裝處理程式時,使用struct sigaction的成員sa_flags中的標誌符sa_siginfo。

clock_id取值為以下:

clock_realtime :systemwide realtime clock.

clock_monotonic:represents monotonic time. cannot be set.

clock_process_cputime_id :high resolution per-process timer.

clock_thread_cputime_id :thread-specific timer.

clock_realtime_hr :high resolution version of clock_realtime.

clock_monotonic_hr :high resolution version of clock_monotonic.

struct sigevent

int sigev_notify; //notification type

int sigev_signo; //signal number

union si**al   sigev_value; //signal value

void (*sigev_notify_function)(union si**al);

pthread_attr_t *sigev_notify_attributes;

union si**al

int sival_int; //integer value

void *sival_ptr; //pointer value

通過將evp->sigev_notify設定為如下值來定製定時器到期後的行為:

sigev_none:什麼都不做,只提供通過timer_gettime和timer_getoverrun查詢超時資訊。

sigev_signal: 當定時器到期,核心會將sigev_signo所指定的訊號傳送給程序。在訊號處理程式中,si_value會被設定會sigev_value。

sigev_thread: 當定時器到期,核心會(在此程序內)以sigev_notification_attributes為執行緒屬性建立乙個執行緒,並且讓它執行sigev_notify_function,傳入sigev_value作為為乙個引數。

啟動乙個定時器:

timer_create()所建立的定時器並未啟動。要將它關聯到乙個到期時間以及啟動時鐘週期,可以使用timer_settime()。

int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspect *ovalue);

struct itimespec;

如同settimer(),it_value用於指定當前的定時器到期時間。當定時器到期,it_value的值會被更新成it_interval 的值。如果it_interval的值為0,則定時器不是乙個時間間隔定時器,一旦it_value到期就會回到未啟動狀態。timespec的結構提供了納秒級解析度:

struct timespec;

如果flags的值為timer_abstime,則value所指定的時間值會被解讀成絕對值(此值的預設的解讀方式為相對於當前的時間)。這個經修改的行為可避免取得當前時間、計算「該時間」與「所期望的未來時間」的相對差額以及啟動定時器期間造成競爭條件。

如果ovalue的值不是null,則之前的定時器到期時間會被存入其所提供的itimerspec。如果定時器之前處在未啟動狀態,則此結構的成員全都會被設定成0。

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

取得乙個定時器的超限執行次數:

有可能乙個定時器到期了,而同一定時器上一次到期時產生的訊號還處於掛起狀態。在這種情況下,其中的乙個訊號可能會丟失。這就是定時器超限。程式可以通過呼叫timer_getoverrun來確定乙個特定的定時器出現這種超限的次數。定時器超限只能發生在同乙個定時器產生的訊號上。由多個定時器,甚至是那些使用相同的時鐘和訊號的定時器,所產生的訊號都會排隊而不會丟失。

int timer_getoverrun(timer_t timerid);

執行成功時,timer_getoverrun()會返回定時器初次到期與通知程序(例如通過訊號)定時器已到期之間額外發生的定時器到期次數。舉例來說,在我們之前的例子中,乙個1ms的定時器執行了10ms,則此呼叫會返回9。如果超限執行的次數等於或大於delaytimer_max,則此呼叫會返回delaytimer_max。

執行失敗時,此函式會返回-1並將errno設定會einval,這個唯一的錯誤情況代表timerid指定了無效的定時器。

刪除乙個定時器:

int timer_delete (timer_t timerid);

一次成功的timer_delete()呼叫會銷毀關聯到timerid的定時器並且返回0。執行失敗時,此呼叫會返回-1並將errno設定會 einval,這個唯一的錯誤情況代表timerid不是乙個有效的定時器。

例1:void  handle()

int main()

例2:void  handle(union si**al v)

int main()

Mysql 檢視定時器 開啟定時器 設定定時器時間

1.檢視是否開啟evevt與開啟evevt。1.1 mysql evevt功能預設是關閉的,可以使用下面的語句來看evevt的狀態,如果是off或者0,表示是關閉的。show variables like sche 1.2 開啟evevt功能 setglobal event scheduler 1 ...

定時器 STM32定時器 基本定時器1

我是鼎!定時器時鐘一定要明確其中有哪些變數。上圖為stm407資料手冊摘出來的,可能看不清楚,其實就蘊含了幾點資訊。注意一點,我們看圖2,我們以apb1舉例,上面掛著很多的外設,包括usart1 adc 以及定時器,我們知道apb1上面最高時鐘頻率為84mhz,但是定時器的時鐘是要在此基礎上乘2,也...

Mysql 檢視定時器 開啟定時器 設定定時器時間

1 1.檢視是否開啟evevt與開啟evevt。23 1.1 mysql evevt功能預設是關閉的,可以使用下面的語句來看evevt的狀態,如果是off或者0,表示是關閉的。4 show variables like sche 5 1.2 開啟evevt功能 6 set global event ...