LabVIEW 的 Single Element Queue

在 LabVIEW 中要使用全域變數,最常見的方法是使用內建的 Global variable 或更具存取控制設計的 Functional global variable (FGV)。本文的主角 Single Element Queue (SEQ) 是以 queue 為基礎所設計的全域變數的存取方式,除了有 by reference 這個特色,另外 SEQ 也符合 LabVIEW 資料流中常見的「初始化」、「讀/寫」與「關閉」的設計概念。

SEQ 的核心精神是創造一個長度為 1 的 queue,要存取的變數的資料型態則在 Obtain Queue 時決定。若要更新變數,將 queue 中的舊內容清除後再 enqueue 新的即可;讀取時則是使用 Preview Queue Element 將變數讀取出來。儲存在 queue 中的變數是以 queue reference 方式來連結,屬於 call by reference 架構。

SEQ 參考程式與範例下載:https://github.com/show6114/LV-SEQ-in-variant

在下圖的 SEQ 範例中,包含 Initialize.vi、Set.vi、Get.vi 與 Close.vi 四個 VI,分別是「初始化」、「寫入」、「讀取」與「關閉」四個變數的操作。這之中 SEQ 的變數是以 variant 來儲存。好處是變數的資料型態較不受挶限(都會先轉成 variant 再傳遞),這一組 SEQ VI 也得以重複使用;缺點是讀取變數時要做 Variant To Data 的轉換(轉換成變數原本的資料型態)。

example.png

Variant To Data 對於大型資料的轉換效率極差。若要存取大型資料,可以將 queue 的資料型態直接固定,雖然這樣一來這組 VI 就會變成專用 VI。另外,對於 cluster 這種複合的資料,可以將變數存成 Type Def.,即使之後變數內容更變了也不會影響到現有程式中 Variant To Data 的轉換。

這邊要注意的是,SEQ 在 Initialize 的時候,包含一個「SEQ name」的設計(詳下圖),這是從 Obtain Queue VI 延伸出來的設計(VI 內部詳下、下圖)。只要在同一個 memory scope 底下,使用相同的 SEQ name 的 SEQ 都可以存取到同一個變數。

init.png

bd-init.png
Initialize.vi 的內容

上圖中 Initialize.vi 包含了 created new? 的判斷,一旦找到了相同 SEQ name 的 queue 就不會 enqueue 變數的初始值(Variant/initial value)進去,讓現值得以保留。

前述 SEQ 中的 Get.vi 是使用 Preview Queue Element VI 來讀取值(下圖),而非與 enqueue 對應的 dequeue 操作,這是因為必需要保留現有值。因為 SEQ 的 queue 長度是 1,若使用 dequeue 就等於把 queue 清空了。

bd-get.png
Get.vi 的內容

小結

SEQ 的概念非常簡單,自己寫也很容易。SEQ 的參考程式與詳細的使用方法可以從前述的連結下載。若有任何問題歡迎留言討論。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s