1. 程式人生 > 資訊 >乘聯會:7 月新能源車出口呈現爆發式增長,特斯拉中國出口 24347 輛

乘聯會:7 月新能源車出口呈現爆發式增長,特斯拉中國出口 24347 輛

程序同步和互斥

程序同步

程序具有非同步性,非同步性指的是各併發執行的程序以各自獨立的、不可預知的速度向前推進

程序通訊--管道通訊

讀、寫程序併發的執行,由於併發必然導致非同步性,因此讀、寫順序的兩個操作執行的先後順序不確定,在實際應用中,又必須寫資料-----讀資料的順序來執行

同步亦稱直接制約關係,它指的是為完成某種任務而建立的兩個或多個程序,這些程序因為需要在某些位置上協調他們的工作次序而產生的制約關係。程序間的直接制約關係就是源於他們之間的相互合作

程序互斥

互斥共享方式,把一個時間段內只允許一個程序使用的資源稱為臨界資源,許多物理裝置都屬於臨界資源。此外,還有許多變數、資料、記憶體緩衝區等都屬於臨界資源

對臨界資源的訪問,必須互斥地進行。互斥、亦稱間接制約關係。程序互斥指當一個程序訪問某臨界資源時,另一個想要訪問該臨界資源的程序必須等待。當前訪問臨界資源的程序訪問結束,釋放該資源後,另一個程序才能去訪問臨界資源

對臨界資源的互斥訪問,可以在邏輯上分為四個部分

進入區:負責檢查是否可進入臨界區,若可以,則應設定正在訪問臨界資源的標誌(可以理解為上鎖),以阻止其他程序同時進入臨界區

臨界區(臨界段):訪問臨界資源的程式碼

退出區:負責解除正在訪問臨界資源的標誌(解鎖

剩餘區:做一些其他處理

為了保持對臨界資源的互斥訪問,同時保持系統整體效能,需要遵循:

1

空閒讓進

臨界區空閒時,可以允許一個請求進入臨界區的程序立即進入臨界區

2

忙則等待

當已有程序進入臨界區,沒他試圖進入臨界區的程序必須等待

3

有限等待

對請求訪問的程序,應保證在有限時間內機內臨界區(保證不會飢餓)

4

讓權等待

當程序不能進入臨界區,應立即釋放處理,防止程序忙等待

程序互斥的軟體實現方法

單標誌法

演算法思想:

每個程序在訪問完臨界區後會把使用臨界區的許可權轉給另一個程序。每個程序進入臨界區的許可權只能被寧另一個程序賦予

同一時刻最多隻有一個程序訪問臨界區

單標誌法的主要問題是違背空閒讓進原則

雙標誌先檢查法

演算法思想:設定一個布林型陣列fagU,陣列中各個元素用來標記各程序想進入臨界區的意願,比如
flag[]=ture”意味著0號程序PO現在想要進入臨界區。每個程序在進入臨界區之前先檢查當前有
沒有別的程序想進入臨界區,如果沒有,則把自身對應的標誌flag設為true後開始訪問臨界

主要問題是忙則等待的原則,不符合互斥原則

原因在於進入區的檢查和上鎖兩個處理不是一氣呵成的,檢查後,上鎖前可能發生程序切換

雙標誌後檢查法

是先檢查法的改版,前一個是先檢查後上鎖,但這兩個不能一氣呵成,導致兩個程序同時進入臨界區的問題。因此用先上鎖後檢查的方法

雖然解決了忙則等待,但又違背了空閒讓進和有限等待的原則,程序會因為長期無法訪問臨界資源產生飢餓現象

peterson演算法

如果都想進,那就嘗試孔融讓梨,主動讓對方先進入臨界區

程序互斥的硬體實現方法

中斷遮蔽方法

利用開關中斷指令實現(與原語的實現思想相同,即在某個程序開始訪問臨界區到結束訪問為止都不允許被中斷,也不能發生程序切換,因為不可能同時發生兩個同時訪問臨界區的情況

關中斷即不允許當前程序被中斷,也必然不會發生程序切換

直到當前程序訪問完臨界區,在執行開中斷指令,才可能有別的程序上處理機並訪問臨界區

優點:簡單、高效

缺點:不適合多核處理機,只適用於作業系統核心程序,不適用於程序使用者(因為開、關中斷指令只能執行在核心態,這組指令讓使用者執行隨意起來會很危險)

TestAndSet指令

簡稱TS,或者TSL指令

是用硬體實現的,執行的過程不允許被中斷,只能一氣呵成

缺點:不滿足讓權等待,暫時無法進入臨界區的程序會佔用cpu並迴圈執行TSL,從而導致忙等

swap指令

又叫Exchange或者XCHG指令

硬體實現的,執行的過程中不允許被中斷,只能一氣呵成

和TSL無太大區別

訊號量機制

訊號量機制有兩種

整形訊號量、記錄型訊號量

使用者程序通過使用作業系統提供的一對原語來對訊號量進行操作,從而很方便的實現了程序互斥、程序同步

訊號量其實就是一個變數(可以是一個整數,也可以是更復雜的記錄型變數),可以用一個訊號量來表示系統中某種資源的數量,比如:系統中只有一臺印表機,就可以設定一個初值為1的訊號量。

原語是一種特殊的程式段,其執行只能一氣呵成,不可被中斷。原語是由關中斷/開中斷指令實現的。軟體解決方案的主要問題是由“進入區的各種操作無法一氣呵成”,因此如果能把進入區、退出區的操作都用“原語”實現,使這些操作能“一氣呵成”就能避免問題。

一對原語指的就是wait(S)和signal(S)原語,可以把理解為自己寫的函式,括號內的訊號量S就是函式呼叫時傳入的一個引數

wait、singal可以簡稱為P\V操作,可以把wait(s)、signal(S)兩個操作分別寫為P(S)\V(S)

整形訊號量

用一個整數來表示系統某個資源的數量

與普通整數變數的區別:對訊號量的操作只有三種,即初始化、P操作、V操作

記錄型訊號量

解決整形訊號量的缺陷存在的忙等的問題,即用記錄型資料結構表示的訊號量

某個程序需要使用資源時,通過wait原語申請

用訊號量機制實現程序一些關係

訊號量機制實現程序互斥

1、先分析併發程序的關鍵活動,劃定臨界區(如:對臨界資源印表機的訪問就在臨界區)

2、設定互斥訊號量mutex,初始值為1

3、在臨界區前執行P(mutex)

4、在臨界區後執行V(mutex)

對不同的臨界資源需要設定不同的互斥訊號量,就像攝像頭、印表機是不同的訊號量

P 、V必須成對出現,缺少P不能保證臨界資源的互斥訪問。缺少V會導致資源永不被釋放,等待程序永不被喚醒

程序同步:要讓各個併發程序按要求有序的推進

分析什麼地方要實現同步關係,保證一前一後

設定同步訊號量S,初始為0

在前操作之後執行V(S)

在後操作之前執行P(S)

訊號量機制實現前驅關係

每一對前驅關係都是一個程序同步問題

1、為每一對前驅關係設定一個同步變數

2.在“前操作”之後對相應的同步變數執行V操作

3.在“後操作”之前對相應的同步變數執行P操作

生產者消費者問題

系統中有一組生產者程序和一組消費者程序,生產者程序每次生產一個產品放入緩衝區,消費者程序每次從緩衝區中取出一個產品並使用。(“產品”理解為某種資料)

生產者、消費者共享一個初始為空、大小為n的緩衝區

只有緩衝區沒滿時,生產者才能把產品放在緩衝區、否則必須等待

只有緩衝區不空時,消費者才能從中取出產品,否則必須等待。

緩衝區屬於臨界資源、各程序必須互斥的訪問

如何實現

順序顛倒的限制性p(empty)操作再執行p(mutex)會對出現死鎖現象,兩類程序都無法進行

因此,實現互斥的P操作一定要在實現同步的P操作之後

V操作不會造成程序阻塞,因此兩個·V操作順序可以交換

把使用產品放在臨界區,會造成短暫性的程序堵塞時間增長,從而導致程序的併發度降低

多生產者-多消費者

多指的時多類

當緩衝區為一、上不上鎖都一樣

如果大於1的緩衝區,就必須設定一個互斥訊號量mutex互斥訪問緩衝區

吸菸者問題

差不多,2333

讀者寫者問題

①允許多個讀者可以同時對檔案執行讀操作:②只允許一個寫者往檔案中寫資訊:;③任一寫者在完成寫操作之前不允許其他讀者或寫者工作;④寫者執行寫操作前,應讓已有的讀者和寫著全部退出,這樣不會造成資料出現錯誤

先分析關係、找之間的互斥和同步

‘兩類程序:寫程序、讀程序

互斥關係:寫寫程序、讀寫程序,但讀讀程序之間不存在互斥問題

整理思路。根據操作確定P、V操作的大致順序

設定訊號量。設定需要的訊號量,根據題目確定訊號量的初始值

潛在問題:如果一個讀者一直在讀程序,寫程序就要等待,一直等待,就會被餓死

如何修改

重點

其實沒那麼死板直接就看這個,其他的也行

哲學家問題

造成死鎖現象

理解死鎖現象就行

管程

訊號量機制會造成編寫程式困難、易出錯

管程是一種高階的同步機制

管程是一種特殊的軟體模組,有一些部分組成

1.區域性於管程的共享資料結構說明
2.對該資料結構進行操作的一組過程
3.對區域性於管程的共享資料設定初始值的語句
4.管程有一個名字

過程就是函式其實

管程的基本特徵

區域性於管程的資料只能被區域性於管程的過程所訪問
一個程序只有通過呼叫管程內的過程才能進入管程訪問共享資料
每次僅允許一個程序在管城內執行某個內部過程

引入管程就是方便實現程序的同步和互斥

1.需要在管程中定義共享資料(如生產者消費者問題的緩衝區)
2.需要在管程中定義用於訪問這些共享資料的“入口”ーー其實就是一些函式(如生產者消費者問題中,可以定義一個函式用於將產品放入緩衝區,再定義一個函式用於從緩衝區取出產品)
3.只有通過這些特定的“入口”才能訪問共享資料
4.管程中有很多“入口”,但是每次只能開放其中一個“入ロ”,並且只能讓一個程序或執行緒進入(如生產者消費者問題中,各程序需要互斥地訪問共享緩衝區。管程的這種特性即可保證個時間段內最多隻會有一個程序在訪問緩衝區。注意:這種互斥特性是由編譯器負責實現的,程式設計師不用關心)
5.可在管程中設定條件變數及等待/喚醒操作以解決同步問題。可以讓一個程序或執行緒在條件變數上等待(此時,該程序應先釋放管程的使用權,也就是讓出“入口”):可以通過喚醒操作將待在條件變數上的程序或執行緒喚醒
程式設計師可以用某種特殊的語法定義一個管程(比如: monitor Producerconsumer....end monitor;),然後其他人就可以根據入口方便的實現同步和互斥
別人都在不停的努力,自己又怎麼會停