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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux timer调用流程图,Linux应用层的定时器Timer使用详解【转】

發(fā)布時(shí)間:2025/3/19 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux timer调用流程图,Linux应用层的定时器Timer使用详解【转】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

linux下定時(shí)器的使用-- alarm() & setitimer():

1、alarm

-------------------------------------------

如果不要求很精確的話(huà),用alarm()和signal()就夠了unsigned int alarm(unsigned int seconds)

函數(shù)說(shuō)明: alarm()用來(lái)設(shè)置信號(hào)SIGALRM在經(jīng)過(guò)參數(shù)seconds指定的秒數(shù)后傳送給目前的進(jìn)程。如果參數(shù)seconds為0,則之前設(shè)置的鬧鐘會(huì)被取消,并將剩下的時(shí)間返回。返回值:

返回之前鬧鐘的剩余秒數(shù),如果之前未設(shè)鬧鐘則返回0。alarm()執(zhí)行后,進(jìn)程將繼續(xù)執(zhí)行,在后期(alarm以后)的執(zhí)行過(guò)程中將會(huì)在seconds秒后收到信號(hào)SIGALRM并執(zhí)行其處理函數(shù)。#include

#include

#include

void sigalrm_fn(int sig)

{

printf("alarm!/n");

alarm(2);

return;

}

int main(void)

{

signal(SIGALRM, sigalrm_fn);

alarm(1);

while(1) pause();

}

2、setitimer()

-------------------------------------------

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

setitimer()比alarm功能強(qiáng)大,支持3種類(lèi)型的定時(shí)器:ITIMER_REAL:

以系統(tǒng)真實(shí)的時(shí)間來(lái)計(jì)算,它送出SIGALRM信號(hào)。ITIMER_VIRTUAL:

-以該進(jìn)程在用戶(hù)態(tài)下花費(fèi)的時(shí)間來(lái)計(jì)算,它送出SIGVTALRM信號(hào)。ITIMER_PROF:

以該進(jìn)程在用戶(hù)態(tài)下和內(nèi)核態(tài)下所費(fèi)的時(shí)間來(lái)計(jì)算,它送出SIGPROF信號(hào)。setitimer()第一個(gè)參數(shù)which指定定時(shí)器類(lèi)型(上面三種之一);第二個(gè)參數(shù)是結(jié)構(gòu)itimerval的一個(gè)實(shí)例;第三個(gè)參數(shù)可不做處理。setitimer()調(diào)用成功返回0,否則返回-1。下面是關(guān)于setitimer調(diào)用的一個(gè)簡(jiǎn)單示范,在該例子中,每隔一秒發(fā)出一個(gè)SIGALRM,每隔0.5秒發(fā)出一個(gè)SIGVTALRM信號(hào):#include

#include

#include

#include

#include

#include

int sec;

void sigroutine(int signo){

switch (signo){

case SIGALRM:

printf("Catch a signal -- SIGALRM /n");

signal(SIGALRM, sigroutine);

break;

case SIGVTALRM:

printf("Catch a signal -- SIGVTALRM /n");

signal(SIGVTALRM, sigroutine);

break;

}

return;

}

int main()

{

struct itimerval value, ovalue, value2;?? ??? ?? //(1)

sec = 5;

printf("process id is %d/n", getpid());

signal(SIGALRM, sigroutine);

signal(SIGVTALRM, sigroutine);

value.it_value.tv_sec = 1;

value.it_value.tv_usec = 0;

value.it_interval.tv_sec = 1;

value.it_interval.tv_usec = 0;

setitimer(ITIMER_REAL, &value, &ovalue);//(2)value2.it_value.tv_sec = 0;

value2.it_value.tv_usec = 500000;

value2.it_interval.tv_sec = 0;

value2.it_interval.tv_usec = 500000;

setitimer(ITIMER_VIRTUAL, &value2, &ovalue);for(;;)

;

}

(1) struct itimerval

struct itimerval {

structtimevalit_interval; /* timer

interval */

struct timeval it_value;??? /* current value */

};

itimerval:?? ?? i?? --> interval

val --> value

itimerval結(jié)構(gòu)中的it_value是減少的時(shí)間,當(dāng)這個(gè)值為0的時(shí)候就發(fā)出相應(yīng)的信號(hào)了.

然后再將it_value設(shè)置為it_interval值.

(2) setitimer()

setitimer()為其所在進(jìn)程設(shè)置一個(gè)定時(shí)器,如果itimerval.it_interval不為0(it_interval的兩個(gè)域都不為0),則該定時(shí)器將持續(xù)有效(每隔一段時(shí)間就會(huì)發(fā)送一個(gè)信號(hào))

注意:Linux信號(hào)機(jī)制基本上是從Unix系統(tǒng)中繼承過(guò)來(lái)的。早期Unix系統(tǒng)中的信號(hào)機(jī)制比較簡(jiǎn)單和原始,后來(lái)在實(shí)踐中暴露出一些問(wèn)題,因此,把那些建立在早期機(jī)制上的信號(hào)叫做"不可靠信號(hào)",信號(hào)值小于SIGRTMIN(SIGRTMIN=32,SIGRTMAX=63)的信號(hào)都是不可靠信號(hào)。這就是"不可靠信號(hào)"的來(lái)源。它的主要問(wèn)題是:進(jìn)程每次處理信號(hào)后,就將對(duì)信號(hào)的響應(yīng)設(shè)置為默認(rèn)動(dòng)作。在某些情況下,將導(dǎo)致對(duì)信號(hào)的錯(cuò)誤處理;因此,用戶(hù)如果不希望這樣的操作,那么就要在信號(hào)處理函數(shù)結(jié)尾再一次調(diào)用signal(),重新安裝該信號(hào)。***********************************

Linux下如何實(shí)現(xiàn)秒以下精確定時(shí)與休眠

linux中提供的休眠函數(shù)是sleep和alarm,但是他們僅僅提供以秒為單位的休眠,這中休眠有些進(jìn)程顯然太長(zhǎng)了,那么怎樣才能使進(jìn)程以更小的時(shí)間分辨率休眠呢?

我知道的方法有2種,下面就做分別介紹。

第一種方法是使用定時(shí)器,Linux提供的定時(shí)器函數(shù)是:

int? setitimer(int which, const struct itimerval *value, struct

itimerval *ovalue);

which指定那種定時(shí)器。Linux提供3種定時(shí)器:

TIMER_REAL:

準(zhǔn)確定時(shí)器,超時(shí)會(huì)發(fā)出SIGALRM信號(hào);

TIMER_VIRTUAL:

虛擬定時(shí)器,只記進(jìn)程時(shí)間,所以會(huì)根據(jù)進(jìn)程執(zhí)行時(shí)間而變化,不能實(shí)現(xiàn)準(zhǔn)確定時(shí),超時(shí)發(fā)出SIGVTALRM信號(hào);

TIMER_PROF:

梗概計(jì)時(shí)器,它會(huì)根據(jù)進(jìn)程時(shí)間和系統(tǒng)時(shí)間而變化,不能實(shí)現(xiàn)準(zhǔn)確定時(shí),超時(shí)發(fā)出SIGPROF信號(hào);

在進(jìn)程中應(yīng)該捕捉所設(shè)定時(shí)器會(huì)發(fā)出的信號(hào),因?yàn)檫M(jìn)程收到定時(shí)器超時(shí)發(fā)出的信號(hào)后,默認(rèn)動(dòng)作是終止。

value是設(shè)置定時(shí)器時(shí)間,相關(guān)結(jié)構(gòu)如下:

struct itimerval {

struct timeval it_interval;

struct timeval it_value;

};

struct timeval {

long tv_sec;

long tv_usec;

};

it_interval指定間隔時(shí)間,it_value指定初始定時(shí)時(shí)間。如果只指定it_value,就是實(shí)現(xiàn)一次定時(shí);如果同時(shí)指定it_interval,則超時(shí)后,系統(tǒng)會(huì)重新初始化it_value為it_interval,實(shí)現(xiàn)重復(fù)定時(shí);兩者都清零,則會(huì)清除定時(shí)器。

tv_sec提供秒級(jí)精度,tv_usec提供微秒級(jí)精度,以值大的為先,注意1s

= 1000000ms。

ovalue用來(lái)保存先前的值,常設(shè)為NULL。

如果是以setitimer提供的定時(shí)器來(lái)休眠,只需阻塞等待定時(shí)器信號(hào)就可以了。

第二種方法是使用select來(lái)提供精確定時(shí)和休眠:

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,

struct timeval *timeout);

n指監(jiān)視的文件描述符范圍,通常設(shè)為所要select的fd+1,readfds,writefds和exceptfds分別是讀,寫(xiě)和異常文件描述符集,timeout為超時(shí)時(shí)間。

可能用到的關(guān)于文件描述符集操作的宏有:

FD_CLR(int fd, fd_set *set);

清除fd

FD_ISSET(int fd, fd_set *set);? 測(cè)試fd是否設(shè)置FD_SET(int fd, fd_set *set);?????設(shè)置fd

FD_ZERO(fd_set *set);???????????? 清空描述符集

我們此時(shí)用不到這些宏,因?yàn)槲覀儾⒉魂P(guān)心文件描述符的狀態(tài),我們關(guān)心的是select超時(shí)。所以我們需要把readfds,writefds和exceptfds都設(shè)為NULL,只指定timeout時(shí)間就行了。至于n我們可以不關(guān)心,所以你可以把它設(shè)為任何非負(fù)值。實(shí)現(xiàn)代碼如下:

int msSleep(long ms) {

struct timeval tv;

tv.tv_sec = 0;

tv.tv_usec = ms;

return select(0, NULL, NULL, NULL, &tv);

}

呵呵,怎么樣,是不是很簡(jiǎn)單?

結(jié)語(yǔ):

setitimer和select都能實(shí)現(xiàn)進(jìn)程的精確休眠,本文分別對(duì)他們進(jìn)行了簡(jiǎn)單介紹,并給出了一個(gè)簡(jiǎn)單的給予select的實(shí)現(xiàn)。我不推薦使用setitimer,因?yàn)橐徽週inux系統(tǒng)提供的timer有限(每個(gè)進(jìn)程至多能設(shè)3個(gè)不同類(lèi)型的timer),再者ssetitimer實(shí)現(xiàn)起來(lái)沒(méi)有select簡(jiǎn)單。

總結(jié)

以上是生活随笔為你收集整理的Linux timer调用流程图,Linux应用层的定时器Timer使用详解【转】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。