• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            Linux下的定時器:alarm()與setitimer()

            Posted on 2008-10-30 18:47 Prayer 閱讀(939) 評論(0)  編輯 收藏 引用 所屬分類: LINUX/UNIX/AIX

            Linux下的定時器有兩種,以下分別介紹:

            1、alarm

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

            unsigned int alarm(unsigned int seconds)

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

            返回值: 返回之前鬧鐘的剩余秒數(shù),如果之前未設(shè)鬧鐘則返回0。

            alarm()執(zhí)行后,進程將繼續(xù)執(zhí)行,在后期(alarm以后)的執(zhí)行過程中將會在seconds秒后收到信號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功能強大,支持3種類型的定時器:

            ITIMER_REAL : 以系統(tǒng)真實的時間來計算,它送出SIGALRM信號。

            ITIMER_VIRTUAL : -以該進程在用戶態(tài)下花費的時間來計算,它送出SIGVTALRM信號。

            ITIMER_PROF : 以該進程在用戶態(tài)下和內(nèi)核態(tài)下所費的時間來計算,它送出SIGPROF信號。

            setitimer()第一個參數(shù)which指定定時器類型(上面三種之一);第二個參數(shù)是結(jié)構(gòu)itimerval的一個實例;第三個參數(shù)可不做處理。

            setitimer()調(diào)用成功返回0,否則返回-1。

            下面是關(guān)于setitimer調(diào)用的一個簡單示范,在該例子中,每隔一秒發(fā)出一個SIGALRM,每隔0.5秒發(fā)出一個SIGVTALRM信號:

            #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 {

            struct timeval it_interval; /* timer interval */

            struct timeval it_value; /* current value */

            };

            itimerval: i --> interval

            val --> value

            itimerval結(jié)構(gòu)中的it_value是減少的時間,當這個值為0的時候就發(fā)出相應(yīng)的信號了. 然后再將it_value設(shè)置為it_interval值.

            (2) setitimer()

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

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

            http://tech.ccidnet.com/art/302/20071226/1322683_1.html

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

            linux中的信號處理(signal和alarm)

            信號是unix中所使用的進程通信的一種最古老的方法.系統(tǒng)使用它來同志一個或多個進程異步事件的發(fā)生.

            linux系統(tǒng)庫bits/signum.h對信號名作了定義:
            linux的大多數(shù)信號是提供給內(nèi)核的,僅有少數(shù)幾種信號可以在信號間發(fā)送.

            .SIGHUP 當終止一個終端時,內(nèi)核就把這種信號發(fā)送給該終端所控制的所有進程.
            .SIGINT 當一個用戶按下中斷鍵(ctrl+c)后,內(nèi)核就向該終端用關(guān)聯(lián)的所有進程發(fā)送這個信號.
            .SIGQUIT 當用戶按下(ctrl+),內(nèi)核就向該終端用關(guān)聯(lián)的所有進程發(fā)送這個信號.
            .SIGILL 當一個進程企圖執(zhí)行一條非法指令時,內(nèi)核就發(fā)送這個信號.
            .SIGFPE 當產(chǎn)生浮點錯誤時,內(nèi)核就發(fā)送這個信號.
            .SIGKILL 這是一個非常特殊的信號,他可以從一個進程發(fā)送到另一個進程,使接收到該信號的進程終止.內(nèi)核偶然也發(fā)送這種信號.
            .SIGALRM 當一個定時器到時的時候,內(nèi)核就發(fā)送這個信號.
            .SIGSTOP 子進程結(jié)束信號.UNIX用它來實現(xiàn)系統(tǒng)調(diào)用exit(),wait();

            信號的處理
            unix的系統(tǒng)調(diào)用signal()用于接受一個指定的信號,并可以指定相應(yīng)的處理方法.

            在linux系統(tǒng)庫signal.h中,它的說明如下:
            signal(int sig,sighandler_t handler);
            sig用于指定信號類型.handle是用于處理該信號的函數(shù).
            handle還可以是:
            .SIG_IGN 忽略這個信號.
            .SIG_DFL 恢復對這個信號的默認處理.

            例如:

            main(){
            signal(SIGINT,SIG_IGN);
            printf(”hello!n”);
            sleep(10);
            printf(”hellon”);
            }
            上面的代碼忽略了SININT信號.

            又例如:
            int catch(int sig);

            main(){
            signal(SIGINT,catch);
            printf(”hello!n”);
            sleep(10);
            printf(”hello!n”);
            }

            int catch(int sig){
            printf(”catch signaln”);
            return 1;
            }
            當用戶按下ctrl+c時,進程被中斷,catch()被執(zhí)行.中斷處理函數(shù)處理完畢后,轉(zhuǎn)回斷點執(zhí)行下面的指令.

            當編寫自己的中斷處理函數(shù)時,注意下面兩點:
            1.信號不能打斷系統(tǒng)調(diào)用.
            2.信號不能打斷信號處理函數(shù).

            alarm(設(shè)置信號傳送鬧鐘)
            定義函數(shù)
            unsigned int alarm(unsigned int seconds);
            函數(shù)說明
            alarm()用來設(shè)置信號SIGALRM在經(jīng)過參數(shù)seconds指定的秒數(shù)后傳送給目前的進程。如果參數(shù)seconds 為0,則之前設(shè)置的鬧鐘會被取消,并將剩下的時間返回。
            返回值
            返回之前鬧鐘的剩余秒數(shù),如果之前未設(shè)鬧鐘則返回0。
            范例
            void handler() {
            printf("hellon");
            }
            main()
            {
            int i;
            signal(SIGALRM,handler);
            alarm(5);
            for(i=1;i<7;i++){
            printf("sleep %d ...n",i);
            sleep(1);
            }
            }
            執(zhí)行
            sleep 1 ...
            sleep 2 ...
            sleep 3 ...
            sleep 4 ...
            sleep 5 ...
            hello
            sleep 6 ...

            http://blog.csdn.net/sambian/archive/2006/04/30/698718.aspx

            久久亚洲私人国产精品vA| 亚洲国产成人久久精品动漫| 欧美一级久久久久久久大| 久久天天躁狠狠躁夜夜不卡 | 欧美噜噜久久久XXX| 久久亚洲中文字幕精品有坂深雪| 久久精品免费观看| 国产精品一区二区久久精品涩爱| 99久久无码一区人妻a黑| 久久精品无码专区免费| 久久久女人与动物群交毛片| 久久综合久久伊人| 久久婷婷综合中文字幕| 浪潮AV色综合久久天堂| 久久人人爽人爽人人爽av| 国产麻豆精品久久一二三| 2019久久久高清456| www亚洲欲色成人久久精品| 日韩人妻无码一区二区三区久久| 久久精品国产精品亚洲下载 | 一本大道久久香蕉成人网| 潮喷大喷水系列无码久久精品| 久久强奷乱码老熟女| 色综合久久88色综合天天| 欧美喷潮久久久XXXXx| 亚洲va中文字幕无码久久| 亚洲一级Av无码毛片久久精品| 久久国产热这里只有精品| 亚洲国产精品婷婷久久| 国内精品久久久久久99| 亚洲乱码精品久久久久..| 亚洲日本va午夜中文字幕久久| 久久高潮一级毛片免费| 99久久精品费精品国产| 狠狠色噜噜狠狠狠狠狠色综合久久| 亚洲国产精品无码久久久不卡| 国内精品人妻无码久久久影院导航 | 久久久久久久波多野结衣高潮| 国产精品久久新婚兰兰| 国产亚洲精品久久久久秋霞 | 亚洲精品乱码久久久久久蜜桃不卡|