Home
Posts
Categories
Series
Tags
About
Process & Thread [三] Coroutines
postedOn: 2025-7-27   updatedOn: 2025-7-27   includedIn: 程式
wordsCount: 1024   readingTime: 3 mins   viewers:

共享資源

優點:

  • 減少記憶體使用量,因為多個協程或線程可以用同一個資源。
  • 提高速度,因為資源已經存在,而不會在需要時創建,結束後銷毀

缺點:

  • 導致競爭條件,因為多個協程或線程可能同時訪問同一份資料,導致資料不一致。
  • 程式碼可讀性和複雜度增加,因為需要考慮如何正確地管理和同步共享資源。(只對初學者是個困難點)

因共享的好處多於壞處,所以會去解決競爭問題=» 通常會用鎖(Lock)來保護共享資源。

(Go 鼓勵用channel來傳遞資料,避免共享資源)

Race condition競爭條件

指多個協程或線程同時訪問共享資源,導致資料不一致的情況。

  • 同時讀取和寫入共享資源。
  • 同時修改共享資源的狀態。

A和B同時讀了資源=5,A要+2,B要+3,最後A以為資源是7,B以為資源是8,實際上不一定,這就是競爭條件。


Lock鎖

確保在同一時間只有一個協程或線程可以訪問共享資源。

Critical section保護對象

指的是需要被保護的共享資源或程式碼區域。

不一定某個值,可能是一段code需要有保證原子性

Lock的使用

  1. 在訪問共享資源之前,先獲取鎖。
  2. 在訪問共享資源之後,釋放鎖。

有上鎖,就必須解開,否則會導致其他協程或線程無法訪問共享資源,造成卡死。

在python中,通常使用with語句來自動管理鎖的獲取和釋放。

在Go中,使用defer語句來確保鎖在函數結束時被釋放。

因一次只能有一個協程或線程可以取鎖,如果只是要讀取,也要做競爭,效率低下,所以有讀寫鎖

Read Write Lock讀寫鎖

讀寫鎖允許多個協程或線程同時讀取共享資源,但在寫入時,會阻止其他協程或線程讀取或寫入。

讀讀ok=>可多個拿讀鎖

寫寫不ok=>只能有一個拿寫鎖

讀寫不ok=>只能有一個拿寫鎖,讀鎖也不能取

使用情境

  • 主要是讀取,偶爾寫入時,使用讀寫鎖可以提高性能。

Dead Lock死鎖

當兩個或多個協程或線程互相等待對方釋放鎖,導致無法繼續執行的情況。

四必要條件

  1. Mutual Exclusion (互斥)
    • 一個資源只能給一個人用
  2. Hold and Wait (保持等待)
    • 持有一個資源,並且正在等待其他資源。
  3. No Preemption (不可搶奪)
    • 資源不能被強制釋放,只能由自行釋放。
  4. Circular Wait (循環等待)
    • 存在互相等待的循環。

實例

  1. A持有鎖1,等待鎖2。 B持有鎖2,等待鎖1,兩人都不放開,卡死
  2. A先拿了讀鎖, 後續自己又要拿寫鎖,因為寫鎖會阻止其他讀鎖,所以A自己卡死自己

避免死鎖(破壞任一必要條件,各種方法)

  1. 一次性拿完所有要拿的鎖
  2. 使用超時機制,一定時間內沒有獲取到鎖,就放棄,手上的鎖也放掉
  3. 確保所有協程或線程按照相同的順序獲取鎖。