2013年2月9日 星期六

非同步程式新手心得: 為什麼要用單一 thread + task queue 的方式設計架構

最近多了一些 GUI + 非同步IO 的開發經驗, 簡記一下心得。

GUI 架構背後的考量

  • 由於 GUI 需要低延遲的反應速度, 必須使用非同步的方式實作。
  • Gtk/Android/iOS 都在 main thread 裡處理畫面顯示和事件 callback 是有道理的。藉由架構保證所有 task (繪圖、偵測事件、事件 callback) 在同一 thread 內執行, 寫程式時不用擔心 race condition。反之, 若將繪圖、偵測事件、事件 callback 三者拆到兩個 threads 以上, 會衍生許多潛在問題。
  • 共享變數太雜時, 使用 global lock + multi-thread 無法提高太多效能, 失去 multi-thread 的意義。
  • 若依各別變數使用不同的 lock 容易寫出問題。
  • 在同一個 thread 內執行內全部的 task, 可以避免使用 lock, 相對省事許多。然後用戶有效能需求時, 針對有需求的部份另開 thread 加速, 減少需要使用 lock 的地方。

實作注意事項

  • 由於程式不是一路通到底, 不適合用以往的直線方式思考。
  • 盡量從環境狀態的角度了解如何處理當下的 task, 而減少保證 task 之間的執行順序。這樣寫起來比較簡單, 也會比較穩定。
  • 程式本身或註解要能表示清楚狀態變化對各 task 的影響。提供 debug flag 可以 log 各 task 執行順序, 或註解提及主要的和特別的 task flow, 應該有助於日後維護。
  • 若能留下產生每個 task 的 task 為何, 有助於日後在 debugger 內除錯。
  • 開始實作以前, 要想清楚可能的狀態變化, 以及留好協助維護的 debug code, 由 debug flag 可以開關。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...