事件佇列

事件佇列

事件佇列(event queue)是指每個事件對應一個佇列項,每個佇列項包括一項事件句柄指針,指向該事件的事件句柄佇列;一項事件種類,它是基本事件之一。每當進行一次通信時,由方法驅動事件按照所需執行的事件種類,將事件對應的程式句柄及其優先權加入到事件程式句柄佇列。

基本介紹

  • 中文名:事件佇列
  • 外文名:event queue
  • 涉及學科:計算機等
  • 套用:Verilog等
  • 意義:每個事件對應一個佇列項
  • 實質:基本事件之一
事件驅動模型,事件佇列初始化,事件驅動時機,事件句柄,事件沖洗,Verilog的層次化事件佇列,動態事件佇列,停止運行的事件佇列,非阻塞事件佇列,監控事件佇列,其他指定的PLI命令佇列,動態事件佇列,非阻塞賦值更新事件佇列和監控事件佇列,RunLoop的事件佇列,簡介,RunLoop的一般套用,

事件驅動模型

事件驅動模型使用三個佇列來管理事件的運行。這三個佇列是,基本事件佇列、事件句柄佇列和待執行句柄佇列。
  • ·基本事件佇列:每個事件對應一個佇列項,每個佇列項包括一項事件句柄指針,指向該事件的事件句柄佇列;一項事件種類,它是基本事件之一;一項本事件未處理的句柄總數,說明還有多少事件等待處理;一項已處理旬柄總數,說明已經發生的事件總數。
  • 事件句柄佇列:每類事件對應一個事件句柄佇列。一個句柄佇列項包括三部分,即程式句柄序列號、事件的程式句柄和事件句柄優先權。序列號區分不同通信時所對應的事件,事件句柄說明該事件發生時執行的程式首地址。
  • 待執行句柄佇列:存放將要執行的事件句柄。事件句柄佇列的事件按優先權存儲在待執行佇列中。處在該佇列中的事件由沖洗程式驅動執行,一次沖洗程式的調用將企圖驅動該佇列中的全部事件的執行。

事件佇列初始化

每當進行一次通信時,由方法驅動事件按照所需執行的事件種類,將事件對應的程式句柄及其優先權加入到事件程式句柄佇列。
除了方法驅動事件之外,一次POST通信至少有如下8個事件發生:套用層方法傳送事件(0)、訊息層傳送事件(10)、數據層傳送事件(20)、傳輸層傳送事件(28)、傳輸層接收事件(8)、數據層接收事件(10)、訊息層接收事件(20)和套用層方法完成事件(30)。

事件驅動時機

當一次通信的事件被初始化後,可以立即驅動事件執行,也可由事件沖洗功能在以後驅動執行。如果每次通信都立即驅動執行,那么事件驅動模型就與層次模型兼容。使用立即驅動方法不能改進通信性能。在格線系統中,主要採用沖洗功能執行事件句柄。採用沖洗功能,若干個通信可以流水地進行,有利於提高系統的通信效率。

事件句柄

當待執行句柄佇列中有事件句柄時,使用事件句柄沖洗功能將佇列中的句柄按優先權和連線標記順序執行。連線標記用來說明本次程式完成之後是繼續(Continue)執行後續句柄指定程式還是就此停止(Stop)。例如,在傳輸層傳送事件之後,應該中止本次事件序列。當傳輸層接收到信號(中斷)時,驅動接收事件序列,直到套用層的方法完成事件為止。HandlerFlush子程式的基本框架如下:
Initialize the connection status to ContinueDO UNTII.all handlers in the waiting list are executed
IF connection status is Stop THEN exit the function
Get handler from handler list based on event priority
Execute program that event handler points to,return result
ENDDO

事件沖洗

當有事件在事件佇列時,可以使用事件沖洗功能。事件沖洗功能對每個事件對應的句柄佇列進行沖洗,每次將具有相同序號的句柄沖洗到等待執行的句柄佇列,並由事件沖洗函式EventFlush(event)沖洗執行佇列,如此重複。EventFlush(event)函式的基本框架如下:
DO UNTII.all events in event queue are processedDisable all”Signals”(interrupt)
IF queue buffer is in used THEN”SIGABRT”is raised
Queue buffers is being checked,and set used to 1
FOR all handlers with the same sequence mark
Find the sDot where this handler should go,and Shift over the lower priority slots
Inserts an event to waiting execute list in non—decreasing order sorted by priority
ENDFOR
Set used flag to no use.and enable”Signals”(interrupt)
Call "HandlerFlush" function
ENDDO

Verilog的層次化事件佇列

詳細地了解Verilog的層次化事件佇列有助於如何理解Verilog的阻塞和非阻塞賦值的功能。所謂層次化事件佇列指的是用於調度仿真事件的不同的Verilog事件佇列。在IEEEVerilog標準中,層次化事件佇列被看作是一個概念模型。設計仿真工具的廠商如何來實現事件佇列,由於關係到仿真器的效率,被視為技術訣竅,不能公開發表,本節也不作詳細介紹。
IEEEl364—1995Verilog標準的5.3節中定義了:層次化事件佇列在邏輯上分為用於當前仿真時間的4個不同的佇列,和用於下一段仿真時間的若干個附加佇列。

動態事件佇列

動態事件佇列(下列事件執行的順序可以隨意安排):
  • 阻塞賦值;
  • 計算非阻塞賦值語句右邊的表達式;
  • 連續賦值;
  • 執行$display命令;
  • 計算原語的輸入和輸出的變化。

停止運行的事件佇列

停止運行的事件佇列:
#0延時阻塞賦值。

非阻塞事件佇列

非阻塞事件佇列:
更新非阻塞賦值語句LHS(左邊變數)的值。

監控事件佇列

監控事件佇列:
  • 執行$monitor命令;
  • 執行$strobe命令。

其他指定的PLI命令佇列

其他指定的PLI命令佇列
以上5個佇列就是Verilog的“層次化事件佇列”。

動態事件佇列

大多數Verilog事件是由動態事件佇列調度的,這些事件包括阻塞賦值、連續賦值、$dis—play命令、實例和原語的輸入變化以及它們的輸出更新、非阻塞賦值語句RHS的計算等。而非阻塞賦值語句LHS的更新卻不由動態事件佇列調度。
在IEEE標準允許的範圍內被加入到這些佇列中的事件只能從動態事件佇列中清除,其他佇列中的事件要等到被“激活”後,即被排人動態事件佇列中後,才能真正開始等待執行。IEEEl364—1995Verilog標準的5.4節介紹了一個描述其他事件佇列何時被“激活”的算法。

非阻塞賦值更新事件佇列和監控事件佇列

在當前仿真時間中,另外兩個比較常用的佇列是非阻塞賦值更新事件佇列和監控事件佇列。非阻塞賦值LHS變數的更新是按排在非阻塞賦值更新事件佇列中,而RHS表達式的計算是在某個仿真時刻隨機地開始的,與上述其他動態事件是一樣的。
$strobe和$monitor顯示命令是排列在監控事件佇列中。在仿真的每一步結束時刻,當該仿真步驟內所有的賦值都完成以後,$strobe和$monitor顯示出所有要求顯示的變數值的變化。
在Verilog標準5.3節中描述的第4個事件佇列是停止運行事件佇列,所有井0延時賦值都排列在該佇列中。採用#0延時賦值是因為對Verilog理解不夠深入的設計人員希望在兩個不同的程式塊中給同一個變數賦值,他們企圖在同一個仿真時刻,通過稍加延時賦值來消除Verilog可能產生的競爭冒險。這樣做實際上會產生問題。因為給Verilog模型附加完全不必要的#o延時賦值,使得定時事件的分析變得很複雜。我們認為採用#0延時賦值根本沒有必要,完全可用其他的方式來代替,因此不推薦使用。

RunLoop的事件佇列

簡介

每次運行RunLoop, 執行緒中的RunLoop會自動處理執行緒中的任務, 並且通知觀察者, 匯報當前的狀態, 順序如下
  1. 通知觀察者RunLoop已經啟動
  2. 通知觀察者任何即將要開啟的定時器
  3. 通知觀察者任何即將要啟動的非基於連線埠的事件源
  4. 啟動任何準備好的非基於連線埠的事件源
  5. 如果基於連線埠的事件源準備好並處於等待狀態, 就立即啟動, 並且進入步驟9
  6. 通知觀察者執行緒即將進入休眠
  7. 將執行緒置於休眠狀態, 直至以下事件的發生
  8. 某一事件到達基於連線埠的源事件
  9. 定時器啟動
  10. RunLoop設定的事件已經逾時
  11. RunLoop被顯式喚醒
  12. 通知觀察者執行緒即將被喚醒
  13. 處理事件
  14. 如果用戶定義的定時器啟動, 處理定時器事件並且重啟RunLoop, 然後進入步驟2
  15. 如果輸入源啟動, 傳遞回響的信息
  16. 如果RunLoop被現實喚醒, 並且事件還沒逾時, 重啟RunLoop, 進入步驟2
  17. 通知觀察者RunLoop結束
事件佇列

RunLoop的一般套用

  • NSTimer和GCD定時器
  • PerformSelector: afterDelay
  • 當調用這個方法的時候, 實際內部會創建一個Timer並且添加到當前的RunLoop中, 如果當前執行緒沒有RunLoop, 這個方法也就會失效
在子執行緒中開啟一個RunLoop, 做為常駐執行緒
自動釋放池
手勢識別等等

相關詞條

熱門詞條

聯絡我們