<aside> ⚠️ 注意:本節為進階語法,初學者可以略過,對後面課程沒有影響。

</aside>

上一節提到我們需要「特徵點辨識」函式傳回兩個陣列,方法之一是將函式建構成一個物件,物件屬性包含AI辨識後要傳回的數值。不過,這個方法會出現錯誤,需要用 actor 解決,所以本節就來了解一下什麼是 actor。

現代電腦的CPU大多具備多核心,例如2020年令筆者非常驚艷的 Apple M1 處理器,包含了8核CPU、8核GPU、16核神經引擎,非常高效又省電,價格還更便宜。可以說,多核處理器已是電腦與智慧型手機的基本配備,但軟體如何善用這些多核處理器呢?

最常用的方法就是程式設計時,儘量用「多執行緒」(multi-thread)執行,讓運算工作分散到不同CPU核心,在同一時脈下,不同核心的工作可同時運算,故又稱為「並行計算」(Concurrent Computing)。

如何設計多執行緒的程式呢?在Swift語言中,最簡單的方式就是用第3單元第7課(3-7a)介紹過的 async/await。async/await 語法是在 Swift 5.5 (2021年)引進,同時間也引進了 actor 語法。在這之前,Swift 多執行緒主要依賴 GCD (Grand Central Dispatch) 機制,就是在上一課(5-9a)用過(但沒有說明)的 DispatchQueue 物件。

actor 用來解決一個特定問題,這個問題是並行計算先天致命之疾,稱為「資料衝突」(data race),要做並行計算遲早會遇到這個問題。

資料衝突是如何發生的呢?我們借用第3單元第7課3-7b的圖稍作修改來解釋「資料衝突」如何發生,如下圖:

截圖 2023-07-23 下午6.06.40.png

若不同執行緒的工作都需要使用(讀、寫)同一筆資料時,就有機會(即使機率很低)發生一個在讀取時,另一個正在寫(更新資料),甚至兩個同時要寫,這時候就會發生無法預期的結果,嚴重時甚至導致軟體閃退,這就稱為 data race(race 是賽跑、競賽,data race 是大家爭搶同一筆資料的意思)。

如何解決呢?在過去,通常需要程式設計師寫額外程式碼來解決這個問題,方法有很多種,但都有點麻煩,牽涉到一些理論,例如用獨佔鎖(lock)或互斥(mutex)等等,不管哪一種解決方案,都必須確保在同一時間只能有一個執行緒可以寫入資料。

actor 背後也有一套理論,但好處是語法簡單,背後理論及處理細節都已隱藏起來,程式設計師只要照語法寫就好。