商業,創業,美食,葡萄酒,閱讀,網路科技。
這是我的 FB粉專 以及 IG,我比較常使用 Threads,歡迎大家追蹤互動~
圖片來源 https://www3.ntu.edu.sg/home/ehchua/programming/java/j5e_multithreading.html
Multi-thread 多執行緒對程式設計來說一直是一個重要的議題,本篇會試圖將自己的一些心得加上可想的到的狀況作一個整理與紀錄。
其中個人經驗 UI thread 與 worker thread 的互動,又與一般系統中的 multi-thread 資料交換有所不同,以下會分開討論。
UI thread 與 worker thread 的互動
無論是有 Graphics 畫面的系統還是 GUI tool,個人經驗中 UI thread 與 worker thread 少有整塊 data buffer 的讀寫,多半是 signal / event / message 的傳遞。
由於 multi-thread 中大量 data 的存取免不了要 lock/unlock,又基本上 UI thread 是不能被 lock 擋的,所以一般 UI thread / worker thread 少有大量資料的傳遞。
不過有一種情況是 UI thread 每個 frame 要從 data source (ex. container) 拿資料出來顯示,當然也會有 worker thread 不定期的更新此 data source,我把此一情形歸為一讀一寫的 multi-thread racing 關係,以下會討論。
一般系統中的 multi-thread 資料交換
我想先敘述一下所謂的 dead lock,因為 dead lock 是 multi-thread 編程中首要避免的。
當 thread1 拿到 lock A,thread2 拿到 lock B,thread1 等 lock B,thread2 等 lock A,此時就 dead lock 了。Dead lock 可能發生的時機是:程式中有兩處以上有 get lock 的動作,且 get lock 後不一定在同一 function release lock。
很多時候同一 function get lock 後就 release lock 了,沒有 dead lock 的問題。那如果因系統需求,而程式寫成可能會發生 dead lock 的狀況,該如何避免?
- 確認所有 thread 拿到多個 lock 的順序是一致的 (上述 thread1, 2 的 case 來說,thread1 拿 lock 的順序是 lock A、B,thread2 拿 lock 的順序是 lock B、A)。但個人很好奇實務上要如何規劃、管理拿 lock 的一致性。
- 系統用一管理器記錄每條 thread 目前拿到的 lock 及其拿到順序。當一條 thread 企圖再拿 lock 時,確認此管理器,如果是會發生 dead lock 的情況則放棄拿此 lock。
multi-thread 同時讀寫的問題
最簡單的做法就是 lock 住要讀寫的 buffer。
討論一下上面的案例:每個 frame 要顯示一定量的 data,另有 worker thread 會不定時的更新 data source。此案例個人的想法是 UI thread 自己 keep 住一個要拿來顯示用的 data buffer,UI thread 在適當時機再更新自己的 data buffer。
那如果 UI thread 在 access data source 時 worker thread 要寫呢?不讓他寫是一個做法,或是準備多個 data buffer 在此情形時讓 worker thread 寫,再找機會更新到真正 data source。運用多個 data buffer,控制讀寫真正 data source 的時機,是解此案例的精神。
Windows 平台解 multi-thread 問題常用的兩個做法:event 和 mutex
Event 上鎖與解鎖是用 ResetEvent
、SetEvent
。
在 thread1 ResetEvent
後,thread2 中如果有 WaitForSignleObject
,則 thread2 會被擋住,直到 thread1 SetEvent
。
Mutex 方面就與一般 multi-thread 保護 data 的概念同:WaitForSignleObject
拿 lock,ReleaseMutex
release lock。
比較 event 與 mutex,個人認為 event 的做法比較像是不同 thread 中處理 event sync 的問題 (當然 event 的做法拿來保護 data 也是可行,但其 API 的配置會變得不直覺)。如果是要在讀寫時保護 data,個人會選擇使用 mutex。
商業,創業,美食,葡萄酒,閱讀,網路科技。