動機

感覺自己不曾了解過Concurrent programming,所以來看這本 看能不能得到一些直覺

共享變量的一致性

  1. 原子性: 在操作時變數的狀態不會被其他人改變
  2. 有序性: 指令產生的效果要照順序發生 (指令重排)
  3. 可見性: 別人改了其他地方看的到嗎? (快取問題)

要看Java Memory Model,會有更好的解釋 同時Java Memory Model也提出一些原則讓我們預期做Concurrent時會發生什麼事 並不限定在Java上他提出的原則是通用的

隔離變數

隔離變數的手法

  1. lock, access in order => 所有變數都在同一個地方
  2. message passing(actor, CSP), copy data(copy-on-write) => 變數在不一樣的地方

避免deadlock

  1. timeout then release => live lock(deadlock doesn’t last forever, no progress is made either)
  2. allow interrupt
  3. check states before do something => CAS(non-lock,atomic var), cond var

avoiding alien method calls while holding a lock are applicable to any language with threads and locks

如何形成deadlock

def procA():
    lockA.lock()
    ...
    lockB.lock()
    ...
def procB():
    lockB.lock()
    ...
    lockA.lock()
    ...

只要在一個瞬間能

  1. 拿到對方想要的資源 (用圖來看就是對方的箭頭指向自己)
  2. 對方拿到自己想要的資源 (自己的箭頭指向對方)
  3. 沒有人願意放開手上的資源
  4. 這些資源都是唯一的只能一個proc持有 (圖的node只能有一個,我打前面三點的時候忘了這個)

Priority inversion(打的時候想起來有讀過,但書上沒有)

高優先序的proc因為其他proc在critical zone而被block, 所以在context switch時讓其他優先序低的proc先執行了

這裡要想到的是critical zone會讓所有用到的proc被綁在一起

在context switch時所有用到critical zone的proc會被綁在一起 因為都要等critical zone

所以可以看成在context switch時可以把proc分成 有/無critical zone

那無critical zone的優先序就是原本的優先序 但有critical zone的優先序是正位於critical zone的proc的優先序

avoid lock

第二章中的第三天提到數字數的程式

原本是只有一個counter從queue拿parser生出的task

第二版把counter生出很多個counter想說可以提升效率 但因為counter們反覆access紀錄結果的map所以基本上沒辦法讓多個counter同時執行

所以把map改成可以Concurrent的map,效率順利上升了

第三版不在把所有counter的紀錄留在同一份map上 而是之後再一次加總完,效率又上去了

就算是可Concurrent的map,但還是會有contention 還是會等(non-lock)

STM與atomic var與actor的比較

In addition to atoms, Clojure also provides agents and refs: • Atoms enable independent, synchronous changes to single values. (atomic var) • Agents enable independent, asynchronous changes to single values. (可以當成actor) • Refs enable coordinated, synchronous changes to multiple values. (STM)

CSP

其實就是pipe,但如何synchronize? 在讀或寫的時候,不能被打斷 並block在讀不到資料時(除非pipe有buffer可以存資料,這樣寫就不會block)

actor與channel可以當成把queue從actor抽出來 獨立讓任何process都能存取