• <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>

            CppExplore

            一切像霧像雨又像風(fēng)

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              29 隨筆 :: 0 文章 :: 280 評論 :: 0 Trackbacks

            作者:CppExplore 網(wǎng)址:http://www.shnenglu.com/CppExplore/
            一、上篇文章描述。文章《定時(shí)器(一)》http://www.shnenglu.com/CppExplore/archive/2008/04/02/46111.html實(shí)現(xiàn)了一個(gè)定時(shí)器模塊,這個(gè)實(shí)現(xiàn)每次延時(shí)時(shí)間到都要掃描所有的定時(shí)器對象,效率低下。開始設(shè)想的時(shí)候,LIST中的定時(shí)器對象保存間隔時(shí)間段的毫秒值,導(dǎo)致每次延時(shí)時(shí)間到都要做“時(shí)間減少操作”直到減少到零,并且得出不需排序的結(jié)論。
            二、改進(jìn)。如果其中保存超時(shí)的精確時(shí)間點(diǎn),而不是保存時(shí)間段,則可以在LIST中根據(jù)超時(shí)時(shí)間點(diǎn)對定時(shí)器對象排序,延時(shí)時(shí)間到,則從鏈表頭掃描定時(shí)器對象,取其超時(shí)時(shí)間點(diǎn)與當(dāng)前時(shí)間點(diǎn)對比,如果小于等于當(dāng)前時(shí)間點(diǎn),則進(jìn)行超時(shí)處理,否則終止繼續(xù)掃描,避免不必要的掃描操作。同時(shí)插入對象的時(shí)候插入到合適的位置,以保持鏈表的順序化。
            三、主要數(shù)據(jù)結(jié)構(gòu)。此次容器結(jié)構(gòu)選擇內(nèi)核數(shù)據(jù)結(jié)構(gòu)中的TAILQ,因?yàn)長IST沒有插入尾部操作(當(dāng)要插入的定時(shí)器對象超時(shí)時(shí)間點(diǎn)大于所有隊(duì)列中的對象的時(shí)候)。
            四、新的時(shí)間類型操作。另一方面很多地方涉及到對struct timeval結(jié)構(gòu)的操作,這里介紹幾個(gè)對該結(jié)構(gòu)進(jìn)行操作的宏,都已經(jīng)在系統(tǒng)頭文件中定義,可以使用函數(shù)原型的方式理解就是如下:

            timeradd(struct timeval *p1,struct timeval *p2,struct timeval *result);
            timersub(struct timeval 
            *p1,struct timeval *p2,struct timeval *result);
            timercmp(struct timeval 
            *p1,struct timeval *p2,operator op);

            對struct timespec同樣有timespecadd/timespecsub/timespeccmp,另外還有兩者的轉(zhuǎn)換宏,使用函數(shù)原型的方式理解就是:

            TIMEVAL_TO_TIMESPEC(struct timeval *p1,struct timespec *result);
            TIMESPEC_TO_TIMEVAL(struct timespec 
            *p1,struct timeval *result);

            如果系統(tǒng)的頭文件中找不到,也可以自己實(shí)現(xiàn)下,明白這兩個(gè)結(jié)構(gòu)的細(xì)節(jié)結(jié)構(gòu),實(shí)現(xiàn)也很簡單,這里拿timeradd舉例,其它不說了。

            #define    timeradd(tvp, uvp, vvp)                        \
                
            do {                                \
                    (vvp)
            ->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;        \
                    (vvp)
            ->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;    \
                    
            if ((vvp)->tv_usec >= 1000000{            \
                        (vvp)
            ->tv_sec++;                \
                        (vvp)
            ->tv_usec -= 1000000;            \
                    }
                                        \
                }
             while (0)
            五、實(shí)現(xiàn)。和上篇文章相比,改動(dòng)比較的在add_timer_和process方法。當(dāng)前add_timer_操作需要順序掃描插入到合適的位置以保持鏈表的順序。當(dāng)前process的主要代碼如下:
            while(manager->m_state==TIMER_MANAGER_START){
                tm.tv_sec
            =manager->m_interval.tv_sec;
                tm.tv_usec
            =manager->m_interval.tv_usec;
                
            while(select(0,0,0,0,&tm)<0&&errno==EINTR);
                gettimeofday(
            &now,0);
            /*加上誤差補(bǔ)償時(shí)間*/
                timeradd(
            &now,&manager->m_repair,&stand);
                pthread_mutex_lock(
            &manager->m_mutex);
                TAILQ_FOREACH(item, 
            &(manager->list_), entry_){
            /*取修正后的時(shí)間逐個(gè)和定時(shí)器中的超時(shí)時(shí)間點(diǎn)相比,遇到不超時(shí)對象則退出掃描*/
                    
            if(timercmp(&item->m_endtime,&stand,<)){
                            
            if(item->m_func)
                                    item
            ->m_func(item,item->m_data);
                         
            if(item->m_type==CTimer::TIMER_ONCE){
                                   manager
            ->remove_timer_(item);
                                  item
            ->m_state=CTimer::TIMER_TIMEOUT;
                            }

                        
            else if(item->m_type==CTimer::TIMER_CIRCLE){
            /*循環(huán)性的要保證鏈表的順序性,如要重新插入,保存entry_的原因,是執(zhí)行新的插入后不要影響當(dāng)前進(jìn)行的循環(huán)*/
                                tmpTimer.entry_
            =item->entry_;
                                manager
            ->remove_timer_(item);
                                manager
            ->add_timer_(item);
                               item
            =&tmpTimer;}
                             }

                     
            else break;
                    }

                    pthread_mutex_unlock(
            &manager->m_mutex);
                }

            六、源碼
            寫了個(gè)簡單的makefile,執(zhí)行make就可以生成測試程序:test,執(zhí)行./test可以看運(yùn)行效果。make由make so和make test組成,make so在lib目錄下生成libtimer.a。make clean清空。
            源代碼下載這里http://www.shnenglu.com/Files/CppExplore/timer.tar.gz  [make so有問題,貌似so是關(guān)鍵字,下載后把so改下,隨意什么單詞。]
            七、后記
            與上一版本相比,該文中的定時(shí)器實(shí)現(xiàn)要求在定時(shí)器模塊運(yùn)行期間不能修改系統(tǒng)實(shí)際,上一版本實(shí)現(xiàn)則無此限制。
            定時(shí)器模塊的鎖初始化為fastmutex方式,因此在回調(diào)函數(shù)里注意不能再調(diào)用CTimer的start stop reset等方法,以免死鎖,如果有調(diào)用的需求,可以把鎖修改為循環(huán)鎖recmutex方式。
             
            2008/4/8補(bǔ)記:本文是timer的v2實(shí)現(xiàn),定時(shí)器timer在業(yè)務(wù)線程中執(zhí)行start的時(shí)候,要執(zhí)行掃描排序操作,導(dǎo)致返回時(shí)間延長。后續(xù)修改:
            (1)定時(shí)器timer的start操作不再執(zhí)行掃描操作,而是簡單插入隊(duì)列頭同時(shí)置一變量表示尚未排序。定時(shí)器線程延遲時(shí)間到,首先掃描未排序?qū)ο螅瑘?zhí)行排序(一次性timer從尾部掃描對比,循環(huán)性從頭部掃描對比),再掃描判斷是否超時(shí)。
            (2)func移動(dòng)到鎖外執(zhí)行。
            針對windows客戶端棧使用定時(shí)器不多,并且定時(shí)間隔不能受系統(tǒng)時(shí)間影響(客戶端的系統(tǒng)時(shí)間可能被修改),仍然使用v1的實(shí)現(xiàn)。
            posted on 2008-04-03 21:49 cppexplore 閱讀(5127) 評論(10)  編輯 收藏 引用

            評論

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2008-09-16 13:41 zam
            很好,能否發(fā)一個(gè)V3版本的源碼給我,非常感謝!
            我的E-mail: zam1208@sohu.com  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2008-10-13 16:11 薛軍
            我也想要一份V3版本的源碼,謝謝!xj181818◎163.com
              回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2008-11-20 14:59 wangwb
            請發(fā)跟我一份吧,學(xué)習(xí)一下,非常感謝!telventbbs@126.com  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2008-12-08 21:51 liujingnan
            我也想要一份V3版,多謝了。liujingnan829@163.com  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2009-02-06 17:06 nihao
            大俠,能不能也給我發(fā)一份v3版本的源碼呀。xujie@m165.com
            多謝!!!!!!!!!!!!  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二)[未登錄] 2009-02-19 10:38 cppexplore
            樓上的各位啊 歡迎來討論理論或者思想 具體到代碼細(xì)節(jié)的東西就免了,文章已經(jīng)很詳細(xì)很詳細(xì)了。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2009-09-28 18:04 neou
            可以去看看linux的定時(shí)器實(shí)現(xiàn)  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二)[未登錄] 2009-09-29 08:30 cppexplore
            @neou
            看過。
            兩碼事情,8253芯片計(jì)時(shí),os里中斷處理。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二)[未登錄] 2010-01-31 22:26 expter
            linux定時(shí)器 是基于時(shí)間輪的,特別對于高性能服務(wù)器效率問題應(yīng)該值得關(guān)注!

            你的插入add_timer 還是單鏈表的排序插入,效率不是很高!
            :)

              回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 定時(shí)器(二) 2010-02-01 11:36 cppexplore
            @expter
            的確不高,呵呵
            現(xiàn)在換成線程獨(dú)自的定時(shí)器了,不再加鎖,容器換簡單的multimap了  回復(fù)  更多評論
              

            欧美亚洲国产精品久久| 国产精品九九久久免费视频 | 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 国产日韩久久久精品影院首页| 久久亚洲AV成人无码电影| 亚洲精品美女久久久久99| 久久久亚洲AV波多野结衣| 国产精品久久新婚兰兰| 久久成人小视频| 亚洲精品白浆高清久久久久久| 久久精品国产免费观看三人同眠| 日本高清无卡码一区二区久久| 亚洲精品成人久久久| 久久久久亚洲AV成人网人人网站| 伊人久久久AV老熟妇色| 精品久久无码中文字幕| 999久久久免费国产精品播放| 精品国产福利久久久| 久久99热这里只有精品国产| 青草久久久国产线免观| 亚洲AV无码久久精品蜜桃| 国产精品美女久久久久网| 国产精品女同一区二区久久| 亚洲国产成人精品无码久久久久久综合| 色欲综合久久躁天天躁| 日本强好片久久久久久AAA| 久久99国产精品久久| 婷婷久久综合九色综合九七| 亚洲va久久久噜噜噜久久| 国产精品一久久香蕉国产线看| 国产午夜电影久久| 精品久久久久久国产| 久久精品免费一区二区三区| 久久只有这精品99| 色综合久久中文色婷婷| 99精品久久久久久久婷婷 | 影音先锋女人AV鲁色资源网久久 | 久久久久亚洲AV无码专区桃色| 三上悠亚久久精品| 理论片午午伦夜理片久久 | 天天综合久久久网|