在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

  • <object id="1jp1h"></object>
    <address id="1jp1h"><nav id="1jp1h"></nav></address>
  • <label id="1jp1h"></label>
    
    

    <bdo id="1jp1h"></bdo>

    新聞中心

    EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 多線程中定時(shí)器的使用

    多線程中定時(shí)器的使用

    作者: 時(shí)間:2016-11-24 來(lái)源:網(wǎng)絡(luò) 收藏
    不管是在進(jìn)程還是線程,很多時(shí)候我們都會(huì)使用一些定時(shí)器之類的功能,這里就定時(shí)器在多線程的使用說(shuō)一下。首先在linux編程中定時(shí)器函數(shù)有alarm()和setitimer(),alarm()可以提供一個(gè)基于秒的定時(shí)功能,而setitimer可以提供一個(gè)基于微妙的定時(shí)功能。 alarm()原型:
    #i nclude
    unsigned int alarm(unsigned int seconds);
    這個(gè)函數(shù)在使用上很簡(jiǎn)單,第一次調(diào)用這個(gè)函數(shù)的時(shí)候是設(shè)置定時(shí)器的初值,下一次調(diào)用是重新設(shè)置這個(gè)值,并會(huì)返回上一次定時(shí)的剩余時(shí)間。
    setitimer()原型:
    #i nclude
    int setitimer(int which, const struct itimerval *value,
    struct itimerval *ovalue);
    這個(gè)函數(shù)使用起來(lái)稍微有點(diǎn)說(shuō)法,首先是第一個(gè)參數(shù)which的值,這個(gè)參數(shù)設(shè)置timer的計(jì)時(shí)策略,which有三種狀態(tài)分別是:
    ITIMER_REAL:使用系統(tǒng)時(shí)間來(lái)計(jì)數(shù),時(shí)間為0時(shí)發(fā)出SIGALRM信號(hào),這種定時(shí)能夠得到一個(gè)精準(zhǔn)的定時(shí),當(dāng)然這個(gè)定時(shí)是相對(duì)的,因?yàn)榈搅宋⒚爰?jí)別我們的處理器本身就不夠精確。
    ITIMER_VIRTUAL:使用進(jìn)程時(shí)間也就是進(jìn)程分配到的時(shí)間片的時(shí)間來(lái)計(jì)數(shù),時(shí)間為0是發(fā)出SIGVTALRM信號(hào),這種定時(shí)顯然不夠準(zhǔn)確,因?yàn)橄到y(tǒng)給進(jìn)程分配時(shí)間片不由我們控制。
    ITIMER_PROF:上面兩種情況都能夠觸發(fā)
    第二個(gè)參數(shù)參數(shù)value涉及到兩個(gè)結(jié)構(gòu)體:
    struct itimerval {
    struct timeval it_interval;
    struct timeval it_value;
    };

    struct timeval {
    long tv_sec;
    long tv_usec;
    };
    在結(jié)構(gòu)體itimerval中it_value是定時(shí)器當(dāng)前的值,it_interval是當(dāng)it_value的為0后重新填充的值。而timeval結(jié)構(gòu)體中的兩個(gè)變量就簡(jiǎn)單了一個(gè)是秒一個(gè)是微秒。
    上面是這兩個(gè)定時(shí)函數(shù)的說(shuō)明,這個(gè)函數(shù)使用本不是很難,可以說(shuō)是很簡(jiǎn)單,但是碰到具體的應(yīng)用的時(shí)候可能就遇到問(wèn)題了,在多進(jìn)程編程中使用一般不會(huì)碰到什么問(wèn)題,這里說(shuō)的這些問(wèn)題主要體現(xiàn)在多線程編程中。比如下面這個(gè)程序
    #i nclude
    #i nclude
    #i nclude
    #i nclude
    #i nclude
    #i nclude

    void sig_handler(int signo)
    {
    alarm(2);
    printf("alarm signal");
    }

    void *pthread_func()
    {
    alarm(2);
    while(1)
    {
    pause();
    }
    }

    int main(int argc, char **argv)
    {
    pthread_t tid;
    int retval;

    signal(SIGALRM, sig_handler);

    if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
    {
    perror("pthread_create");
    exit(-1);
    }

    while(1)
    {
    printf("main thread");
    sleep(10);
    }
    return 0;
    }
    這個(gè)程序的理想結(jié)果是:
    main thread
    alarm signal
    alarm signal
    alarm signal
    alarm signal
    alarm signal
    main thread
    可事實(shí)上并不是這樣的,它的結(jié)果是:
    main pthread
    alarm signal
    main pthread
    alarm signal
    main pthread
    為什么會(huì)出現(xiàn)這種情況呢?是因?yàn)榘l(fā)送給工作線程的信號(hào)中斷的主線程的sleep,并且這個(gè)中情況只影響主線程而不會(huì)影響到其他的工作線程。我們?cè)趺床拍芙鉀Q這種問(wèn)題呢,最簡(jiǎn)單的方法是修改這個(gè)程序,修改這個(gè)線程主線程使用alarm,工作線程使用sleep。這樣就能夠達(dá)到我們的要求,但是有時(shí)候有不能簡(jiǎn)單的這樣操作。所以我們就需要進(jìn)一步的修改我們的程序。在這里我第一個(gè)想到的是使用signal(SIGALRM, SIG_IGN),可是這個(gè)是設(shè)置整個(gè)進(jìn)程對(duì)這個(gè)信號(hào)的響應(yīng)方式,經(jīng)過(guò)測(cè)試也確實(shí)不能完成我期望的功能,那么怎么辦呢?有這樣一個(gè)函數(shù)pthread_sigmask,線程中的信號(hào)屏蔽,函數(shù)的原型及相關(guān)函數(shù)為:
    #i nclude
    int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
    函數(shù)中第一個(gè)參數(shù)how有三個(gè)值SIG_BLOCK、SIG_SETMASK和SIG_UNBLOCK這里我們是用第二個(gè)值SIG_SETMASK
    int sigemptyset(sigset_t *set);
    int sigaddset(sigset_t *set, int signum);
    然后我們改造我們的程序?yàn)椋?br />#i nclude
    #i nclude
    #i nclude
    #i nclude
    #i nclude
    #i nclude

    void sig_handler(int signo)
    {
    alarm(2);
    printf("alarm signal");
    }

    void *pthread_func()
    {
    alarm(2);
    while(1)
    {
    pause();
    }
    }

    int main(int argc, char **argv)
    {
    pthread_t tid, tid_1;
    int retval;

    signal(SIGALRM, sig_handler);

    if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
    {
    perror("pthread_create");
    exit(-1);
    }

    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);
    pthread_sigmask(SIG_SETMASK,&sigset,NULL);

    while(1)
    {
    printf("main pthread");
    sleep(10);
    }
    return 0;
    }
    這個(gè)時(shí)候我們就能夠看到我們想要的結(jié)果了。
    這里再附一個(gè)setitimer的使用范例
    #i nclude
    #i nclude
    #i nclude
    #i nclude
    #i nclude
    #i nclude

    struct itimerval timerval;
    void sig_handler(int signo)
    {
    printf("alarm signal");
    }


    void *pthread_func()
    {

    setitimer(ITIMER_REAL, &timerval, NULL);
    while(1)
    {
    pause();
    }
    }

    int main(int argc, char **argv)
    {
    pthread_t tid;
    int retval;
    timerval.it_interval.tv_sec = 2;
    timerval.it_interval.tv_usec = 0;
    timerval.it_value.tv_sec = 2;
    timerval.it_value.tv_usec = 0;

    signal(SIGALRM, sig_handler);

    if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
    {
    perror("pthread_create");
    exit(-1);
    }

    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);
    pthread_sigmask(SIG_SETMASK,&sigset,NULL);

    while(1)
    {
    printf("main thread");
    sleep(5);
    }




    return 0;

    }



    關(guān)鍵詞: 多線程定時(shí)

    評(píng)論


    技術(shù)專區(qū)

    關(guān)閉
    ×

    “芯”朋友见面大会
    珠海|11.14|泰克“芯”朋友见面大会珠海站|泰克带您从测试角度看半导体的整条产业链,快来报名抢位吧>>