ACE中的定時器實現原理

2021-09-30 10:01:41 字數 1156 閱讀 6434

最近專案中遇到乙個問題,用ace框架起的定時器,跑著跑著,它不跑了,然後我依賴定時器所建立的任務也一直掛在那裡。檢視系統軟體列印的日誌發現,是ace的ace_reactor在run_reactor_event_loop函式中返回了-1,reactor的時間迴圈結束,從而導致定時器函式handle_timeout函式無法再被觸發。為了找出問題的具體原因,看了一把ace的原始碼,雖然到目前為止,為何run_reactor_event_loop函式返回-1的原因還沒找到,但我卻意外的發現了ace驅動定時器的原理(僅限於linux平台)。

利用ace_reactor來建立乙個定時器主要是呼叫scheldule函式,ace_reactor的schedule函式會呼叫它在linux下得工具類ace_select_reactor_t的schedule函式,ace_select_reactor_t類中有乙個ace_timer_queue_t的成員變數,這個變數中儲存著該ace_reactor建立的所有定時器的資訊,包括定時器的事件物件(ace_event_handle為基類的子類物件,這個物件中的handle_timeout函式即定時器的觸發函式)、定時間隔、下次定時器被觸發的時間(絕對時間)等。ace_reactor進行事件迴圈時會呼叫select函式阻塞等待被啟用的控制代碼,select函式的最後乙個入參是乙個描敘時間的結構體,如果在結構體描敘的時間裡還是沒有等待到乙個啟用的控制代碼,那麼函式將會返回0,退出等待。ace_reactor正是利用select的這個特性,即實現了io事件迴圈的處理也實現定時器事件迴圈的處理。其具體的操作為:

1、從ace_timer_queue_t佇列中找出最近會被觸發的時間器的觸發時間

2、將上述取到的時間減去當前時間,並將其作為select的最後乙個引數傳入select中,

3、select函式返回後(要麼有io控制代碼被啟用,要麼到了需要執行定時器函式的時間),在ace_timer_queue_t中檢測是否有需要被觸發的定時器(觸發時間已到,即將執行時間-當前時間<=0?),依次修改這些觸發時間已到的定時器的下次執行的時間,並呼叫觸發函式;在控制代碼集合中查詢是否有啟用狀態的控制代碼,並進行處理(呼叫handle_*函式)

4、重複1、2、3的操作(迴圈)

這就是ace裡面定時器的實現原理,由此可見ace的定時器還是會存在很多缺陷的,例如,如果乙個ace_reactor中起了幾個定時器,而某些定時器的觸發函式需要執行較長得時間,那麼必會導致一些定時器函式被觸發的時間不準確。

Spring Spring中定時器實現

在一些工作需要使用到定時器,spring 很好的整合了定時器的功能!在spring 中使用quartz,本文介紹spring3.0以後自主開發的定時任務工具,spring task,可以將它比作乙個輕量級的quartz,而且使用起來很簡單,除spring相關的包外不需要額外的包,下面介紹兩種方式實現...

ACE反應器模型的應用 定時器

反應器的 schedule timer 函式用來設定乙個定時事件,當時間到達時 事件處理器的 handle timeout 處理函式。schedule timer 的原型如下 schedule timer ace event handler event handler,const void arg,...

Java web中簡單的定時器實現

scheduledexecutorservice executor executors.newscheduledthreadpool 1 executor.scheduleatfixedrate new echoserver 0,times,timeunit.milliseconds 單位毫秒 st...