SICP讀書筆記 3 4

2022-07-04 07:24:09 字數 3660 閱讀 9070

讓我們舉起杯,祝福那些將他們的思想鑲嵌在重重括號之間的lisp程式設計師 !

祝我能夠突破層層**,找到住在裡計算機的神靈!

1. 構造過程抽象

2. 構造資料抽象

3. 模組化、物件和狀態

4. 元語言抽象

5. 暫存器機器裡的計算練習答案

在引入賦值後,迫使我們需要關心事件發生的順序,從而引發了併發的問題

限制並行程序之間的交錯情況

對共享變數的序列訪問

建立一些不同過程的集合,並且保證在每個個序列化集合中至多只有乙個過程的執行

(parallel-execute ) ;;併發的過程集

;;加入序列化就可以保證獨立的執行

(define s (make-serializer))

(parallel-execute )

;;訪問款

(define (make-account balance)

(define (withdraw amount)

(if (>= balance amount)

(begin (set! balance (- balance amount))

balance)

"insufficient funds"))

(define (deposit amount)

(set! balance (+ balance amount))

balance)

(let ((protected (make-serializer)))

(define (dispatch m)

(cond ((eq? m 'withdraw) (protected withdraw))

((eq? m 'deposit) (protected deposit))

((eq? m 'balance) balance)

(else (error "unknown request -- make-account"

m))))

dispatch))

如果希望交換兩個賬戶的餘額就需要對整個過程進行序列化

(define (make-account-and-serializer balance)

(define (withdraw amount)

(if (>= balance amount)

(begin (set! balance (- balance amount))

balance)

"insufficient funds"))

(define (deposit amount)

(set! balance (+ balance amount))

balance)

(let ((balance-serializer (make-serializer)))

(define (dispatch m)

(cond ((eq? m 'withdraw) withdraw)

((eq? m 'deposit) deposit)

((eq? m 'balance) balance)

((eq? m 'serializer) balance-serializer)

(else (error "unknown request -- make-account"

m))))

dispatch))

(define (deposit account amount)

(let ((s (account 'serializer))

(d (account 'deposit)))

((s d) amount)))

(define (serialized-exchange account1 account2)

(let ((serializer1 (account1 'serializer))

(serializer2 (account2 'serializer)))

((serializer1 (serializer2 exchange))

account1

account2)))

序列化的實現
通過基本的互斥元的同步機制來實現序列化。互斥元是一種物件,有兩種基本的操作,獲取和釋放,一旦互斥元被獲取後,任一獲取互斥元的操作都需要等到該互斥元被釋放

(define (make-serializer)

(let ((mutex (make-mutex)))

(lambda (p)

(define (serialized-p . args)

(mutex 'acquire)

(mutex 'release)

val))

serialized-p)))

互斥元的實現

(define (make-mutex)

(let ((cell (list false)))

(define (the-mutex m)

(cond ((eq? m 'acquire)

(if (test-and-set! cell) ;;如果mutex已經被獲取了那麼就持續獲取這個互斥元直到它被釋放

(the-mutex 'acquire)))

((eq? m 'release) (clear! cell))))

the-mutex))

(define (clear! cell)

(set-car! cell false))

(define (test-and-set! cell) ;;必須支援原子操作才可能正確

(if (car cell)

true

(begin (set-car! cell true)

false)))

死鎖
發生在獲取執行緒時產生衝突時,每個程序都需要無窮無盡的等待另乙個程序的活動

避免死鎖

在進行序列化時,為每個程序都安排乙個唯一標識,使每個程序都優先進去較低標識標號的賬戶。這一就不會產生乙個交錯的衝突,但是還是存在一些情況,需要更複雜的技術

併發性、時間和通訊

在如今,為了實現高速處理器,出現了流水線、快取技術,所以並不能保證儲存器每刻都保持一致,但像test-and-set!這樣的操作都需要檢查乙個全域性變數,所以序列化技術已經被其他新技術代替了

在分布式系統中,基本的現象是不同程序之間的同步,建立起共享狀態,或迫使程序之間通訊所產生的事件都按照某種特定的順序進行。從本質上看,在併發控制中,任何時間概念都和通訊有著內在的密切聯絡。

這一節主要講的是在引入了賦值後,有關併發的概念,提出了一種解決方法:序列化,有關序列化的關鍵應該是持有的互斥元。最後作者提出了在有關併發的問題中,任何的時間概念都必然和通訊存在著內在的密切聯絡,個人理解也就是說併發實際是在控制事件的發生和物件與物件之間的通訊順序。

讀書筆記(二) SICP

1.3.1 formulating abstractions with higher order procedures 讀了兩三遍才明白higher order procedure是什麼。乙個固定的procedure形成了乙個固定的pattern,這些patterns我們可以通過用abstracti...

Effective C 讀書筆記 34

條款34 區分介面繼承和實現繼承 在對base class 進行public繼承的時候,根據base class中成員函式的型別我們能夠得到不同的繼承方式 如下 class shape class rectangle public shap 在上面的類shap中,成員函式draw是pure的,因此c...

SICP讀書筆記1 練習1 22的思考

1.對於沒有賦值語句的程式如何實現引數改變 1 遞迴呼叫改變引數 比如,我要實現檢驗輸入的引數begin是乙個偶數還是奇數,如果是奇數進行下一步,如果是偶數就 1將其設定為奇數。程式如下 define search for primes begin counter if remainder begi...